Improve the async-to-sync wrapper (#744)

* improved async to sync wrapper

* Create a new loop in non-main threads & improve readability

* Do not run_coroutine_threadsafe unless it's outside the loop

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
This commit is contained in:
rking32 2021-08-29 15:35:48 +05:30 committed by GitHub
parent e68da74e89
commit bacc7c004b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -40,23 +40,33 @@ def async_to_sync(obj, name):
try: try:
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
except RuntimeError: except RuntimeError:
loop = main_loop loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
if loop.is_running(): if threading.current_thread() is threading.main_thread():
if threading.current_thread() is threading.main_thread(): if loop.is_running():
return coroutine return coroutine
else: else:
if inspect.iscoroutine(coroutine): if inspect.iscoroutine(coroutine):
return asyncio.run_coroutine_threadsafe(coroutine, loop).result() return loop.run_until_complete(coroutine)
if inspect.isasyncgen(coroutine): if inspect.isasyncgen(coroutine):
return asyncio.run_coroutine_threadsafe(consume_generator(coroutine), loop).result() return loop.run_until_complete(consume_generator(coroutine))
else:
if inspect.iscoroutine(coroutine):
if loop.is_running():
async def coro_wrapper():
return await asyncio.wrap_future(asyncio.run_coroutine_threadsafe(coroutine, main_loop))
if inspect.iscoroutine(coroutine): return coro_wrapper()
return loop.run_until_complete(coroutine) else:
return asyncio.run_coroutine_threadsafe(coroutine, main_loop).result()
if inspect.isasyncgen(coroutine): if inspect.isasyncgen(coroutine):
return loop.run_until_complete(consume_generator(coroutine)) if loop.is_running():
return coroutine
else:
return asyncio.run_coroutine_threadsafe(consume_generator(coroutine), main_loop).result()
setattr(obj, name, async_to_sync_wrap) setattr(obj, name, async_to_sync_wrap)