Bug report
Bug description:
asyncio.loop.sendfile() does not reliably report native sendfile unavailability when fallback=False.
The documentation says:
Raise SendfileNotAvailableError if the system does not support the sendfile syscall and fallback is False.
However, the actual exception depends on the transport mode:
TRY_NATIVE transport where native sendfile fails:
raises SendfileNotAvailableError
FALLBACK transport, such as SSL/TLS:
raises RuntimeError("fallback is disabled and native sendfile is not supported ...")
- unsupported transport:
raises RuntimeError("sendfile is not supported ...")
This makes it hard for callers to reliably detect that native sendfile is unavailable. Catching RuntimeError is too broad, because it can also indicate unrelated states such as a closing transport or an unsupported
transport object.
For example, in aiohttp there is a project specific sendfile fallback implementation, which is more efficient than asyncio's fallback.
I did a small PR aio-libs/aiohttp#12945
which illustrates performance difference but there is no reliable way to detect that loop.sendfile can't be used with a particular transport. So I had to use private members from asyncio to do that.
It would be nice to just have the following logic:
try:
loop.sendfile(transport, ..., fallback=False)
except asyncio.SendfileNotAvailableError:
_sendfile_fallback(...)
But, it doesn't work for at least SSL transports.
Suggested fix:
Always raise SendfileNotAvailableError when native sendfile for transport can't be used and fallback=False
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Bug report
Bug description:
asyncio.loop.sendfile()does not reliably report native sendfile unavailability whenfallback=False.The documentation says:
However, the actual exception depends on the transport mode:
TRY_NATIVEtransport where native sendfile fails:raises
SendfileNotAvailableErrorFALLBACKtransport, such as SSL/TLS:raises
RuntimeError("fallback is disabled and native sendfile is not supported ...")raises
RuntimeError("sendfile is not supported ...")This makes it hard for callers to reliably detect that native sendfile is unavailable. Catching
RuntimeErroris too broad, because it can also indicate unrelated states such as a closing transport or an unsupportedtransport object.
For example, in
aiohttpthere is a project specific sendfile fallback implementation, which is more efficient than asyncio's fallback.I did a small PR aio-libs/aiohttp#12945
which illustrates performance difference but there is no reliable way to detect that
loop.sendfilecan't be used with a particular transport. So I had to use private members from asyncio to do that.It would be nice to just have the following logic:
But, it doesn't work for at least SSL transports.
Suggested fix:
Always raise
SendfileNotAvailableErrorwhen native sendfile for transport can't be used andfallback=FalseCPython versions tested on:
CPython main branch
Operating systems tested on:
Linux