9 ms·
Async Views in Django 3.1
- stickyricky 6y ago> Writing asynchronous code gives you the ability to speed up your application [...] Citation needed... It will be slower by definition but it probably advertised higher throughput anyway. I wonder how many people the throughput question is true for. You’d have to be pretty hardware constrained. They even suggest asyncio could be a replacement for celery... It really is the Wild West out here.
- calpaterson 6y ago> They even suggest asyncio could be a replacement for celery... It really is the Wild West out here. Yes that is complete madness. The last thing I would ever want to do is send an email or use an external API (those are the examples in TFA) in an async thread as part of a request-response cycle. How does error handling or retries work for that background stuff? I don't know the exact ins-and-outs of Djangos new async stuff yet but my guess is that if that mail/API server doesn't respond to your IO then your response to your own HTTP request hangs? Above all the central and undemonstrated claim is that there are any performance or management advantages to async. I tested sync vs async on this a couple of months ago. The best performance and robustness is with garden variety sync python with a good WSGI server: http://calpaterson.com/async-python-is-not-faster.html http://calpaterson.com/async-python-is-not-faster.html If anyone has any contradictory benchmarks please let me know. I haven't been made aware of any yet.
- rahuldj 6y agoTechempower benchmark: https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext&l=zijzen-1r https://www.techempower.com/benchmarks/#section=data-r19&hw=... makes the difference between async python frameworks and sync frameworks pretty clear. Async results in better utilization of system resources... since there aren't entire threads with app state blocked on IO requests (which would consume a chunk of system memory.) Considering that a web app is most commonly waiting for a database operation, a single server can serve many more active requests simultaneously (since each active request is not allocating an app instance.)
- calpaterson 6y agoThe techempower benchmark predates me and original drafts of my blogpost mention it but I suppose that got cut for various reasons. The trouble with that benchmark is that (and they're fairly open about this) they aren't keeping things the same between frameworks - there are multiple variables. If you look at the Flask code all the queries are being put through SQLAlchemy but for various async frameworks they're using the database driver directly and using native code libraries for JSON decoding. I think techempower's benchmarks are interesting but they don't help you do a comparision of async vs sync. Additionally on the particular benchmark you've linked to #1 is a dead experimental framework that is not in wide use and #2 is Falcon, a sync framework that is in wide use.
- deleted 6y ago[deleted]
- toxik 6y agoYeah the post conflates asynchronous and concurrent like people always do. Asynchronous code can be executed sequentially, people. (Synchronous code can be executed concurrently, too.) Asynchronous code is absolutely not just for running tasks after returning an HTTP response. A good example of the true power of asynchronous execution would be to do a Web Socket handler _inside a Django view._
- fiedzia 6y ago> They even suggest asyncio could be a replacement for celery Only if you don't care about reliability.
- nickjj 6y ago> They even suggest asyncio could be a replacement for celery... It really is the Wild West out here. Yeah this is pretty questionable. Having state in your app's process and then having to pretty much re-invent queues, job cancellation, uniqueness guarantees, scheduled jobs, periodic jobs on an interval, queue draining and retries with exponential backoffs. I mean, yeah you could code all of that with enough time but why would you when Celery exists. If anything having the queue's state held in Redis or anywhere outside of your app's process is enough of a reason to pretty much never replace Celery with asyncio. Even in the post's example of sending an email I would still want a lot of what Celery has to offer and wouldn't consider replacing it. IMO Celery isn't going anywhere soon and I would still use it in every Python project that needs background processing.
- sbelskie 6y agoJust based on my C# experience, this sounds like a terrible idea (abandoning a real task queue for Async/await). 90% of the “gotchas” with async/await in C# comes from people thinking that the task scheduler is bonafide background queue.
- mayama 6y agoSame here. We do lot of processing in background jobs, which make no sense moving to async task.
- earthboundkid 6y agoCelery doesn’t guarantee uniqueness. :-/
- collyw 6y agoI used Celery (as a workaround) for a Django view that should have been in asyncio before asynchio was available.
- agumonkey 6y agosomehow the idea reminds me of continuations based responses (HN used to be wired that way, also Queinnec wrote lisp papers on the topic)
- Epskampie 6y agoI'm very familiar with symfony, but not so much with django or other "persistent in memory" web frameworks. Can someone ELI5 what the advantage is to async django? Does it mean the server doesn't block on one request before handling the next?
- fiedzia 6y agoYes. Typically to serve several requests at the same time, you'd run multiple processes, each handling an at a time, and if you spend a lot of time waiting for io (database, some service call or slow client), you'll need to use a lot of workers (each being independent python+django instance, so its a lot of memory -> significant investment in hardware). Async is nothing new in Python world, but previously you'd have to resort to pure python to use it, now you have whole django ecosystem that will use it. So main benefit is that you can handle more requests on the same django instance, and pay less for hardware.
- throwaway13337 6y agoI recently moved some code base from py/django to c#/aspdotnetcore. C# probably has some of the best async primitives of any language. I still managed to be bitten by the very common issue of error logging getting lost in a hidden callback that doesn't look like a callback because of the magic of the async keyword (a common issue in node as well). I'm convinced that the async style of web servers is largely a step in the wrong direction. A leaky abstraction that we don't need. A better model already exists - thread per connection - for the majority of what we want as web developers. There are some good things about allowing us to manage our own waits but those things are rare. It reminds me of the choice of when to manage your own memory - usually we don't need to, but sometimes we do. Most languages programmers use today decided, rightly, that memory management was an exception and not the norm. We are more productive today for the reduction in cognitive load for most applications as we decide not to manage our own memory. Thread per connection has gotten a bad name for performance which is pretty false. You can create the exact same underlying abstraction with green threads for more concurrency when you absolutely need it (but mostly you don't). The code we get from not using async is reduced in complexity substantially. I'm disappointed that django is on the async bandwagon. It means that I may have to make another framework choice in the future.
- GiorgioG 6y agoAs a C#/.NET developer I couldn't agree more - more often than not most of us simply do not need async, but everyone's doing it so it's become a 'best practice.'
- merb 6y agowell the problem is that if you use it once it's probably easier to use it everywhere. most people understand it if I show them a task explorer or ps and call Thread.Sleep and Task.Delay. I've never had an Issue with C# async and before I was a big scala user and did not have probems at all.
- melolife 6y agoThe new async Razor engine in .NET Core is ridiculous. They threw out view helper functions and support for functional/monadic control flow for what, so you can asynchronously render a string? Insane. I suspect the actual motivation is that async is virtually required to address performance problems associated with the new tag helpers - which are themselves a terrible, terrible idea. Slow, brittle, surprising, wholly reliant on syntax highlighting, and then redundant because you can implement the same functionality using the existing C# syntax.
- zests 6y agoI've done asynchronous programming with the reactive paradigm where I specify a chain of function calls I want applied to data and it happens in a thread independent way. I have not done much programming with the new fancy "async/await" keywords. It seems like a worse abstraction because it mixes asynchronous code with synchronous code and is probably harder to reason about. Not to mention you can't do something like application wide backpressure unless everything is asynchronous. Can anyone who has worked in both types of applications comment on their differences?
- calpaterson 6y agoI would say that there are maybe three different ways of async rather than two. Broadly: - wholly implicitly (by monkeypatching stuff with gevent typically) - async/await - by reactor (twisted) async/await is not really an alternative to the explicit style of twisted. To paraphase Guy Steele it is an attempt to drag the monkeypatchers halfway to twisted. It doesn't really solve the problem of mixing sync code in with your async code, the only preventative to that is programmer diligence. If you read from a file using open in the middle of your async code you're going to block the process while bytes are gathered for you. However it does prevent you from accidentally using async code in the middle of your sync code. Problems like backpressure and failure handling are largely unsolved in asyncio.
- dtech 6y agoI've done both, but 80% in reactive streams. I like async/await before it has a lot less hard stuff to think about - hot and cold streams take months if not years for devs to grok - and creates code a lot more similar to non-async code. In contrast Reactive Streams requires you to change your complete program. I like to compare it to Typescript/Kotlin-style null-safety v.s. the Java Optional or Scala Option. If you want make code null safe with option you have to rewrite basically your complete code from "procedural" to chains of (flat)maps. In contrast in Typescript you just change T to T? in a few places and add an if where you want to handle the optionality. async/await versus reactive streams has this same problem, reactive streams is highly impactful, much more than async/await. In practice I've seen this have the effect of turning applications turn into a small reactive stream outer shell with the app itself being mostly synchronouse/Future, while async/await is used a lot more liberally because the impact is smaller. > It seems like a worse abstraction because it mixes asynchronous code with synchronous code It doesn't, at least in Kotlin only an async function can call an async function. This isn't different from using `map` in a stream.
- holler 6y agoFor anyone looking for an alternative python async web framework, I highly recommend Starlette (https://github.com/encode/starlette https://github.com/encode/starlette). It was created by the same guy who wrote the excellent & highly popular Django-Rest-Framework. Very lightweight, clean, well-documented, and a breeze to get running with. It also supports async tasks natively. I spent years working with Django and now I'm currently using it to power the api for https://sqwok.im https://sqwok.im.
- jordic 6y agoWe are also using starlette and works quite well.. in combination with asyncpg..
- holler 6y agovery nice! cool animations on tmpo.io! Right now I'm running things behind aws lambda & using dynamodb etc, have looked into using aioboto3 but haven't got there yet...
- toinbis 6y agoDo you use any db connection wrappers around asyncpg? Like encode/databases or gino? Also important to note that SQLAlchemy 1.4 alpha with asyncpg support is realease and can be tried out(both SQLAlchemy core&orm modes support it). I myself evaluated all options of async postgress connection wrappers in fastapi project but reverted to... just using sync psycopg2 through sqla core. No very specific gains of async db connection for my use cases and sqlalchemy creator's comments on immaturity of async postgres drivers made my stick to what's battletested.
- jordic 6y agoOn one project we use Databases, with a custom opensourced "adapter" for sqlalchemy models: https://github.com/vinissimus/asyncom https://github.com/vinissimus/asyncom Our cms, is based on Guillotina (https://github.com/plone/guillotina https://github.com/plone/guillotina) that uses a Datastore more or less equivalent to the Zodb, and plone, but internally uses postgresql and asyncpg. We are active contributors on it, and since latest version it works around asgi (uvicorn). We also have some plans to make it a bit more psqlidiomatic (get rid of pickles, ....) On other internal services, we use the raw asyncpg.pool, mostly because part of our bussiness logic it's inside prostgresql, and this doesn't feet super well with an ORM. Think on a 15 year old sql schema, that had evolved through different hands, and right now it's multitenant xD Latest opensourced thing, it's a work queue based on plgsql, with asyncpg bindings. (https://github.com/vinissimus/jobs/ https://github.com/vinissimus/jobs/). So, we can say, we use asynpg in all possible forms.
- jordic 6y agoWith async Django views we can use Django with asyncpg... o_o but middlewares are still synch...
- zaro 6y agoYeah, it will be some more years before you can simply write async stuff in Django and not worry about every single library that you use, whether it supports async or not. That's why some years ago I gave up on Django altogether and moved to Nodejs. Much better experience writing async code.
- jordic 6y agoOur front service it's a nextjs/nodejs project. But I still prefer python :) and our API's are python based, typed async python.. but python..
- kabacha 6y agoI really don't get this anti-async mentality on HN. Maybe I'm doing something wrong but async is a complete game changer for me as there just so much IO wait in every project I touch. The fact that my program has to stop and wait for something is honestly unacceptable and it's just a logical conclusion to eliminate this blockage. I worked past 2 years with asyncio and I have to say it still kinda sucks. The syntax is overly verbose and asyncio itself can't decide what it wants to be. However it still works _good_ for the most part and there's an enormous community and effort in this!
- BozeWolf 6y ago“So much io wait”. What io is your app waiting for? Is it a webserver, or another type of app?
- naters 6y agoNot the GP, but I'm currently working on a small web app that synchronizes data from 2 other web services, which means that almost every endpoint involves a call to an external API. In some cases, it involves repeated calls to those APIs, but the order in which the responses are received is unimportant, which is an ideal use case for asyncio's gather function. Using a framework (I haven't tried Django's new async views yet, but am using one of the handful of Flask-ish async frameworks) that supports async views has made this a snap, whereas before I would probably have used some sort of out-of-process work queue type setup.
- esseti 6y agois there a list of real use cases where the async is better than the sync. it seems that it's ok in very edge casees where there's high load and a lot of I/O (example, calling external APIs, calling a db). however, is it stable enough and roboust to replace sync methods in production for the benefit of these cases?