== Notes == * `asyncio.run()` gets the event loop, runs tasks until they're complete, and closes the event loop. Introduced in Python 3.7 and replaces `asyncio.get_event_loop()` and `loop.run_until_complete()`. E.g. {{{#!highlight python numbers=off asyncio.run(main()) }}} rather than: {{{#!highlight python numbers=off loop = asyncio.get_event_loop() try: loop.run_until_complete(main()) finally: loop.close() }}} * CPU-intensive things should not be in async tasks. Put them into ProcessPoolExecutor, e.g. {{{#!highlight python import asyncio import concurrent.futures executor = concurrent.futures.ProcessPoolExecutor() item = ... # do something CPU-intensive against this cpu_intensive_thing = ... # some CPU-intensive function async def cpu_intensive_coroutine(item): loop = async.get_event_loop() result = await loop.run_in_executor(executor, cpu_intensive_thing(item)) return result result = asyncio.run(cpu_intensive_coroutine(item)) }}} * Python 3.9 has `async.to_thread()` which is a higher level of the above but into a ThreadPoolExecutor. It's only useful for IO-bound tasks. * use `async.create_task` to turn a coroutine into a task. Tasks can be given to gather or as_comepleted * `asyncio.gather` will schedule multiple async tasks at once. Waits for all tasks to be completed, returns list of results. ( `asyncio.as_completed` can be looped over as tasks are completed. {{{#!highlight python tasks = [] tasks.append(asyncio.create_task(…)) tasks.append(asyncio.create_task(…)) # … for completed_task in asyncio.as_completed(*tasks): earliest_task_results = await completed_task # … }}} == Helpers == * `asynctosync` and `synctoasync` helpers: https://github.com/django/asgiref/blob/master/asgiref/sync.py, usage: https://www.aeracode.org/2018/02/19/python-async-simplified/. Also: [[https://pypi.org/project/syncasync/|pip package: syncasync]] == Links == [[http://www.dabeaz.com/coroutines/Coroutines.pdf|A Curious Course on Coroutines and Concurrency]] * [[https://redislabs.com/blog/async-await-programming-basics-python-examples/|Async/Await Programming Basics with Python Examples for Redis]]: examples of `async.gather()` w/ Redis API * [[https://realpython.com/async-io-python/|AsyncIO in Python: A Complete Walkthrough]]: great overview * [[https://www.pythonsheets.com/notes/python-asyncio.html|Asyncio PySheeet]]: reference snippets * https://fredrikaverpil.github.io/2017/06/20/async-and-await-with-subprocesses/ * https://docs.python.org/3/library/asyncio-task.html#asyncio.gather * https://stackoverflow.com/questions/48483348/how-to-limit-concurrency-with-python-asyncio * https://stackoverflow.com/questions/46031558/how-to-limit-the-number-of-concurrent-processes-using-subprocess-module-in-async * https://docs.python.org/3/library/asyncio-sync.html#asyncio.Semaphore