3 ms·
This article doesn't evaluate the case that you actually want ASGI for, so I don't think it's very useful. (Or at least, it confirms something that should have
by theptip 6y ago
This article doesn't evaluate the case that you actually want ASGI for, so I don't think it's very useful. (Or at least, it confirms something that should have already been clear).
If you're compute-bound, then Python async (which uses cooperative scheduling similar to green threads) isn't going to help you. You get parallelism, but not concurrency from this progamming model; only one logical thread of execution is running on the CPU at a time (per-process), so this can only slow you down if you are CPU-constrained.
The standard usecase of a sync API backed by a local DB with low request latency is typically going to be compute-bound.
This is covered in the Django async docs (https://docs.djangoproject.com/en/3.1/topics/async/ https://docs.djangoproject.com/en/3.1/topics/async/) and also in green threading libraries like gevent (http://www.gevent.org/intro.html#cooperative-multitasking http://www.gevent.org/intro.html#cooperative-multitasking).
The case where async workers are interesting is for I/O-bound workloads. Say you're building an API gateway, or your monolithic API starts to need to call out to other API services, particularly external ones like Google Maps API. In this case, the worst-case result is that the proxied HTTP request times out; this could block your Django API's work thread for many seconds.
In the async / green-threaded model, this case is fine; you have a green thread/async function call per request, and if that gthread is blocked on an upstream I/O operation, the event loop will just start working on a different API call until the OS gives a response on the network socket.
Essentially, there's no reason to use Django async if you're doing a traditional monolithic DB-backed application. It's going to give you benefits in usecases where the standard sync model struggles.
(Note, there's an argument that you might want green threads even in a normal monolith, to guard against cases like "developer accidentally wrote a chunky DB query that takes 60 seconds to run for some inputs", but most DB engines don't support one-DB-connection-per-HTTP-connection. There was a bunch of discussion on this topic a few years ago, with the SQLAlchemy author arguing that async is not useful for DB connections: https://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/ https://techspot.zzzeek.org/2015/02/15/asynchronous-python-a... although asyncio support was added: https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.htm...)
- leafboi 6y agoThe tests aren't compute bound. They are testing requests per second. It's testing biased towards IO, not compute. Please read the article.
- theptip 6y agoI read the article, thanks. I think you've missed my point. I'll TL;DR it for you to make it clearer: > This article doesn't evaluate the case that you actually want ASGI for, so I don't think it's very useful. > The standard usecase of a sync API backed by a local DB with low request latency is typically going to be compute-bound. (Note, I'm specifically talking about Django here) > Essentially, there's no reason to use Django async if you're doing a traditional monolithic DB-backed application. It's going to give you benefits in usecases where the standard sync model struggles. My claim is that these benchmarks are not looking at the use-case that Django async is intended to solve. It's not about increasing throughput to your local DB, and so it's not surprising that you don't see an improvement in benchmarks testing that case. Django's async is intended to enable API-gateways and other long-running requests where the upstream latency can be long enough to starve your API worker threads. Regarding compute-bound vs. I/O-bound, I'm sure YMMV, but my APM tracing for a mature non-trivial production Django API shows that waiting on the DB accounts for about 25% of the total request time across all my endpoints. Serialization/deserialization takes an embarrassing amount of time in Django, see https://news.ycombinator.com/item?id=24161828 https://news.ycombinator.com/item?id=24161828 for example. This framework is optimized for developer productivity, not for performance.
- DangitBobby 6y ago> The standard usecase of a sync API backed by a local DB with low request latency is typically going to be compute-bound. > This is covered in the Django async docs Where is this mentioned in the linked docs? I see four mentions of the ORM in the linked pages, including where it says they are working on async ORM, but I see nothing about performance for the ORM typically being compute bound.