Last active
April 2, 2023 07:02
-
-
Save mikeckennedy/c76739766ce072f980aa4df1a6dc9516 to your computer and use it in GitHub Desktop.
Convert an async method to a synchronous one.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
import functools | |
from typing import Any, Coroutine | |
loop = asyncio.new_event_loop() | |
def run(async_coroutine: Coroutine[Any, Any, Any]): | |
""" | |
Convert an async method to a synchronous one. | |
Example: | |
async def some_async_method(x, y): ... | |
result = syncify.run( some_async_method(1, 2) ) | |
Args: | |
async_coroutine (): | |
Returns: The value returned by `async_coroutine` | |
""" | |
return loop.run_until_complete(async_coroutine) |
Thanks for your answer @mikeckennedy, long and slow running tasks are important to consider.
I had a preference to high-level APIs because I was planning to teach this approach (syncify) but with the least possible complexity.
You're welcome. You might look into what they are suggesting in this Stackoverflow answer:
https://stackoverflow.com/questions/39400885/await-for-any-future-asyncio/39407084#39407084
async def main():
futures = [loop.run_in_executor(None, fetch, x) for x in range(50)]
while futures:
done, futures = await asyncio.wait(futures,
loop=loop, return_when=asyncio.FIRST_COMPLETED)
for f in done:
await f
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You could definitely implement it with: asyncio.wait(...) and return_when=ALL_COMPLETED. But if you encounter a long running task, it could start to back up the entire async flow. This way as soon as a task gets done, it gets dropped into the done queue ineffectively is finished for the process. I do realize, that if the first task is the slow running task it's the same thing here. But at least, in a slightly more complicated way above, as soon as a task is done in order, it's available for pick up. And the other task can still be running. So if you have many short tasks, they won't affect the latency as much.
That's what I was thinking anyway. :-)