I have some questions related to the usage of async. At what scale(in terms of number of users or server load) would choosing async based web frameworks over traditional web frameworks like Django/Pylons make sense?
While using async is much easier with the new async/await syntax compared to traditional async solutions like twisted, tornado etc., a lot of popular database connectors and ORMs do not support async currently.
Even if the libraries a person needs are present at the moment, there's always the chance that a library maybe required in the future that does not support async and it may not be feasible to write a replacement(either due to the person's lack of expertise or due to lack of funds to hire someone else to write it).
In such a case, would using a traditional library by spawning threads to run any blocking operation be a good stop-gap solution(until an async replacement comes along)?
In general, mixing synchronous and asynchronous I/O typically brings you the worst in both worlds.
This has been a nightmare in C# which pioneered async/await - a lot of developers are struggling with footguns from mixing sync and async code.
Ryan Dhal said that he picked JavaScript for Node because he was afraid of this and wanted a language without synchronous APIs already built in.
I think Python 3.5+ async/await is fantastic don't get me wrong - but if you want to mix and match I'd recommend getting a second server that runs the synchronous framework and then communicating over network (REST HTTP for example) between the completely asynchronous server and the one running the thread pool.
> This has been a nightmare in C# which pioneered async/await - a lot of developers are struggling with footguns from mixing sync and async code.
The big difference is that C# supports both multithreading and parallelism out of the box. Python has multithreading but with a GIL, nodejs has none of the 2.
> At what scale(in terms of number of users or server load) would choosing async based web frameworks over traditional web frameworks like Django/Pylons make sense?
Using async makes sense where you want to handle 100s/1000s of long-open connections (websockets for instance). Spawning a lot of threads/processes can be very expensive, and will lead to suboptimal QoS.
> While using async is much easier with the new async/await syntax compared to traditional async solutions like twisted, tornado etc., a lot of popular database connectors and ORMs do not support async currently.
Good news is that you can have most of your application written in Django (or other traditional web framework), using async to implement specific API endpoints.
It depends on if you're CPU bound or IO bound. If you're CPU bound - switching to an async based web framework may not help that much. If you're IO bound, and you're using synchronous web workers that are sitting idle waiting from responses from databases, etc... an async approach might work better. I don't necessarily think asyncio is the answer though, when you can just (for the most part) drop in gevent or eventlet which provides coroutines that you can use as light-weight threads that can perform IO bound work concurrently with out much change to your codebase.
At work, we use Flask+Gevent for our HTTP API. It's worked pretty well so far!
> In such a case, would using a traditional library by spawning threads to run any blocking operation be a good stop-gap solution(until an async replacement comes along)?
For the record, asyncio provides this ability out-of-box using the AbstractEventLoop.run_in_executor coroutine.
Neither Django nor Flask is asynchronous/event loop based. It would neither make sense nor improve performance to run a Django/Flask app on top of uvloop. If you want to develop a web API using uvloop, you should look at aiohttp (http://aiohttp.readthedocs.io/en/stable/).
Aiohttp is the next layer up the stack, it just utilizes whichever event loop policy is active. So basically it just makes it faster in most (all?) async things it does.
I use aiohttp and uvloop fairly heavily, though I've not formally benched with/without uvloop in quite some time.
As far as I know, the only issue is that we don't support Windows atm. Which in most cases is fine -- you can develop on windows using vanilla asyncio, and use uvloop when deploying on *nix.
As a heavy user of asyncio and uvloop, I haven't found any downsides yet (well, other than no windows support if you're on windows). Async Python takes a little learning, but generally speaking I think it's one of the cleanest implementations of async programming to date.
I also recommend to read our blog posts about uvloop and asyncio on magic.io