Some updates (mostly formatting) to asyncio post

This commit is contained in:
Chris Hodapp 2018-03-09 23:01:35 -05:00
parent 7a775321ff
commit dfd9080d81

View File

@ -25,14 +25,16 @@ over to some other code, whereas calling "whenever" means retaining
control but queuing up some code to be run in the background
asychronously (as much as possible).
| Call from | Call to | When | How |
|-----------+-----------+----------+-----------------------------|
| Either | Function | Now | Normal function call |
| Function | Coroutine | Now | `.run_*` in event loop |
| Coroutine | Coroutine | Now | `await` |
| Either | Function | Whenever | Event loop `.call_*()` |
| Either | Coroutine | Whenever | Event loop `.create_task()` |
| | | | `asyncio.ensure_future()` |
| Call from | Call to | When/where | How |
|-----------+-----------+-----------------------+-----------------------------------------------|
| Either | Function | Now, same thread | Normal function call |
| Function | Coroutine | Now, same thread | ~.run_*~ in event loop |
| Coroutine | Coroutine | Now, same thread | ~await~ |
| Either | Function | Whenever, same thread | Event loop ~.call_*()~ |
| Either | Coroutine | Whenever, same thread | Event loop ~.create_task()~ |
| | | | ~asyncio.ensure_future()~ |
| Either | Function | Now, another thread | ~.run_in_executor()~ on ~ThreadPoolExecutor~ |
| Either | Function | Now, another process | ~.run_in_executor()~ on ~ProcessPoolExecutor~ |
* Futures & Coroutines
@ -44,15 +46,15 @@ coroutines and futures. My summary on what I figured out is below.
It just happens that both allow you to call things asychronously.
However, you can use coroutines/asyncio without ever touching a
Future. Likewise, you can use a Future without ever touching a
coroutine or asyncio. Note that its `.result()` call isn't a
coroutine or asyncio. Note that its ~.result()~ call isn't a
coroutine.
** They can still encapsulate each other.
A coroutine can encapsulate a Future simply by `await`ing it.
A coroutine can encapsulate a Future simply by using ~await~ on it.
A Future can encapsulate a coroutine with [[https://docs.python.org/3/library/asyncio-task.html#asyncio.ensure_future][asyncio.ensure_future()]] or
the event loop's [[https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task][.create_task()]].
A Future can encapsulate a coroutine with [[https://docs.python.org/3/library/asyncio-task.html#asyncio.ensure_future][asyncio.ensure\_future()]] or
the event loop's [[https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task][.create\_task()]].
** Futures can implement asychronicity(?) differently
@ -79,13 +81,14 @@ which is available only when a coroutine has been scheduled to run.
on a project. I ran into many issues with this combination. Qt's
juggling of multiple event loops seemed to cause many problems here,
and I still have some unsolved issues in which calls
`run_until_complete` cause coroutines to die early with an exception
~run_until_complete~ cause coroutines to die early with an exception
because the event loop appears to have died. This came up regularly
for me because of how often I would want a Qt slot to queue a task in
the background, and it seems this is an acknowledge [[https://github.com/harvimt/quamash/issues/33][issue]].
There is also [[https://github.com/MagicStack/uvloop\][uvloop]]. I have no need for extra performance (nor could
I really use it alongside Qt), but it's helpful to know about.
There is also [[https://github.com/MagicStack/uvloop\][uvloop]]. I presently have no need for extra performance
(nor could I really use it alongside Qt), but it's helpful to know
about.
# Also: What about coroutine generators?
# Are they anything special?