Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dropping the GIL while performing non-blocking IO can be detrimental for some server workloads. Consider the case where a single Python process is doing a mix of asyncio and compute bound tasks (running in background threads). If the compute bound tasks don't drop the GIL (or only drop it for a fraction of the time), then the background threads may acquire and hold the GIL during every call to `uv_run` (which should return quickly, since all socket operations are non-blocking). This can tank IO performance (for more information, see https://bugs.python.org/issue7946). For example, running the enclosed echoserver benchmark as follows: ``` $ python echoserver.py --uvloop --buffered --proto --gil ``` On master: ``` $ python echoclient.py --num 1000 will connect to: ('127.0.0.1', 25000) Sending 1000 messages Sending 1000 messages Sending 1000 messages 3000 in 19.91612672805786 150.63169867128815 requests/sec ``` This PR: ``` $ python echoclient.py will connect to: ('127.0.0.1', 25000) Sending 200000 messages Sending 200000 messages Sending 200000 messages 600000 in 9.143043279647827 65623.66398675856 requests/sec ``` This change may not be beneficial for all workloads. This will prioritize waiting IO over waiting background compute threads. I suspect for a server context this is usually what you'd want (and is what we want for dask), but other users may differ. If needed, we could make this a configurable setting on the loop without a ton of effort.
- Loading branch information