socketify.py/src/socketify/loop.py

65 wiersze
2.2 KiB
Python
Czysty Zwykły widok Historia

import asyncio
import threading
import time
2022-05-31 20:53:20 +00:00
def loop_thread(loop, exception_handler):
if hasattr(exception_handler, '__call__'):
loop.set_exception_handler(lambda loop, context: exception_handler(loop, context, None))
loop.run_forever()
def future_handler(future, loop, exception_handler, response):
try:
future.result()
return None
except Exception as error:
if hasattr(exception_handler, '__call__'):
exception_handler(loop, error, response)
else:
try:
#just log in console the error to call attention
print("Uncaught Exception: %s" % str(error))
if response != None:
response.write_status(500).end("Internal Error")
finally:
return
class Loop:
2022-05-31 20:53:20 +00:00
def __init__(self, exception_handler=None):
self.loop = asyncio.new_event_loop()
2022-05-31 20:53:20 +00:00
if hasattr(exception_handler, '__call__'):
self.exception_handler = exception_handler
self.loop.set_exception_handler(lambda loop, context: exception_handler(loop, context, None))
else:
self.exception_handler = None
asyncio.set_event_loop(self.loop)
self.loop_thread = None
def start(self):
2022-05-31 20:53:20 +00:00
self.loop_thread = threading.Thread(target=loop_thread, args=(self.loop,self.exception_handler), daemon=True)
self.loop_thread.start()
def stop(self):
#stop loop
self.loop.call_soon_threadsafe(self.loop.stop)
#wait loop thread to stops
self.loop_thread.join()
# Find all running tasks in main thread:
pending = asyncio.all_tasks(self.loop)
# Run loop until tasks done
self.loop.run_until_complete(asyncio.gather(*pending))
2022-05-31 20:53:20 +00:00
def run_async(self, task, response=None):
future = asyncio.run_coroutine_threadsafe(task, self.loop)
future.add_done_callback(lambda f: future_handler(f, self.loop, self.exception_handler, response))
return future
2022-06-01 23:00:05 +00:00
# if sys.version_info >= (3, 11)
# with asyncio.Runner(loop_factory=uvloop.new_event_loop) as runner:
# runner.run(main())
# else:
# uvloop.install()
# asyncio.run(main())