Implement sendfile support.
Specifically two event loop methods are still missing:
-
loop.sock_sendfile(..) -
loop.sendfile(..)
Both were added to asyncio 3.7.
To clarify the requirement here: is the plan to leverage some support from libuv or is this a matter of replicating the code from vanilla asyncio?
The only reference to sendfile I seem to find in libuv is:
http://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_sendfile
Unfortunately, the libuv's sendfile implementation is just a thin wrapper over the "sendfile" system call. I.e. uv_fs_sendfile() is not integrated with uv_tcp_t handles, so it's very similar to Python's os.sendfile(). This means that yes, what we'll need to do is similar to vanilla asyncio, and I think that using os.sendfile() should be easier for us (will ensure same error types/messages as in asyncio).
In terms of the actual implementation: first we'll need a loop.sock_sendfile() method, which should be relatively simple to implement. This should probably be the first PR.
The second PR should add loop.sendfile(). This one is more tricky; we'll need to:
-
use
uv_poll_thandles to temporary monitor read activity foruv_tcp_tanduv_pipe_thandles; -
replicate asyncio's logic with pausing and resuming reading as well as exhausting write buffer before doing sendfile;
-
replicate sendfile fallback implementation to support it for SSL transports.
Good news is that a lot of the above is already figured out in asyncio, so we just need to apply that knowledge to the slightly different IO implementation in uvloop.