|
|
|
|
|
by zzzeek
1334 days ago
|
|
since it's my job to clear these things up, a few pointers: 1. python has threads. they just cannot perform CPU bound tasks in parallel due to the GIL. The GIL is released for IO, so threads can perform IO waiting in parallel, just like asyncio
2. asyncio runs in one thread, and has the exact same limitations as threads as implemented in Python, CPU operations are serialized, async tasks can yield for IO. the advantages offered by asyncio are: 1. you can have thousands of tasks extremely quickly cheaply, which is not as much the case for threads in Python . this can allow for massive concurrent architectures more expediently, provided your concurrency is very IO bound (if you are CPU bound, disaster) 2. people just like asyncio's programming model, IMPO this is largely due to the popularity of Javascript's event-based model being natural for lots of newer programmers |
|
For server-side code, I'd still probably use threads up to maybe 1000 concurrent connections. Beyond that, I've used gevent to good effect. e.g., I have a server that receives HTTP POSTs which are multipart forms, the form having 3 parts, a JSON part and two file parts. The two files parts get written to files on S3 and the JSON part to SQS. The web framework is Falcon[1] and I also made use of a Cython-based HTTP form parser[2]. Concurrency is handled via gevent. Openresty sits in front and invokes the Python server via uwsgi. At the time I developed it, asyncio was not yet mature and not supported by boto3. I benchmarked against pypy but unsurprisingly (since it's I/O bound) got better performance and from CPython + gevent.
If I were developing it from scratch today, I'd re-evaluate the asyncio story, or more likely than not, choose a different language.
I don't doubt that there's use-cases to which asyncio is well-suited and the right choice, but I suspect folks may be using it in cases where they'd be fine with threads. As always, there are trade-offs.
1. https://falconframework.org/
2. https://pypi.org/project/streaming-form-data/ (I think)