Hacker News new | ask | show | jobs
by lilbobbytables 3218 days ago
> That seems wrong. I should be able to run normal Python code as async, right?

No, that is not the case. To better understand this you should look at an async library, like https://github.com/aio-libs/aiohttp Look at what it actually calls all the way down under the hood.

If it were as simple as adding `asyncio.sleep(0)`, then that library seems as though it would have been much easier to write. :P

Just look at the code you posted at the end, it actually runs faster synchronously, without `asyncio.sleep(0)`. The sleep is what happens async, not the print statements, therefore, all you're doing is introducing delay.

Similarly, the Django ORM DB calls you make in the other examples are all still happening synchronously. However, you're just adding a delay that causes them to get picked off in an inconsistent order.

1 comments

So what you're saying is it needs an 'async' version of the Django ORM for the example to work

In other words what is really needed is an ORM that would allow you to write:

  source = await Source.objects.get(id=source_id)
  await source.update()
(?)
Yes, in a cooperative async model anything which would block will stop progress of every coroutine, so you would need an async version of the ORM library for this to work. When you await something, you're telling the event loop to stop running this coroutine, and wait for something (usually IO) to happen before resuming execution. Because of this, if you block on IO without using await, the coroutine doesn't know to yield and will simply pause; thus execution of every single coroutine is blocked.

This leads to a sort of infectious need to make everything async as even a single non cooperating coroutine can bring the whole show to a halt. It's essentially the red vs blue function problem of Python. However, there is actually a nice alternative, gevent. gevent will monkey patch all functions in the standard library which would block, e.g. reading from a socket, attaching an implicit await to them. If the author has used gevent, the example Django code would actually work as expected, since the code would execute until the database connection was written to/read from and then immediately await.

Either way, async IO is still a somewhat tricky thing to understand and get right. It took writing a non blocking event loop with epoll in my case to really grok what was going on under the hood of something like asyncio.