-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use os.sendfile() when available #1448
Comments
How much time does your profiling data say you're spending in this part of the code? |
It wastes both time and memory. Sending files is something that can be done very efficiently with With |
Here is an example where sendfile() is used on a non-blocking socket: |
When The loop in StaticFileHandler is already fairly simple and memory-efficient (note that |
Just wanted to mention this, but I'm sure you're already aware. But in Python 3.5, there's now |
I ended up here by accident. Just wanted to point out that using sendfile() makes an actual difference. In pyftpdlib (I'm the author) transfers on localhost by using sendfile() vs. send() are nearly 3 times as fast so I think such an addition to Tornado should be seriously taken into consideration. Famous softwares such as proftpd, vsftpd, nginx and samba all implement sendfile support.
As for how to integrate this into Tornado IO loop you can take a look at how this is done in pyftpdlib:
Last: I am thinking about rewriting pyftpdlib by using Tornado because it provides an HTTP client, coroutines and support for easily integrating threads/processes to avoid blocking calls. |
Any News? |
Any latest news on this? Any way we can use os.sendfile with some http server in Python? |
I think this is unlikely to happen so I'm going to go ahead and close this issue as "unplanned". Now that we're unconditionally wrapping the asyncio event loop, the functionality is available at the lowest level via that interface. But at the HTTP level, supporting sendfile would involve breaking a lot of abstractions and would only work in limited circumstances (no TLS, etc). I don't think this is a good fit for Tornado. That leaves IOStream, where I think there is some chance that a sendfile interface might make sense. I might be willing to accept a PR to add this. But overall my recommendation would be that if you care about sendfile you're probably better off working with asyncio protocols and transports rather than IOStream (which is designed to do a lot of buffering). |
The
StaticFileHandler
should useos.sendfile()
if available. While static files would commonly be sent by an external webserver (nginx etc.) in a production environment, sometimes files are generated on the fly and need to be written out through the IOLoop.sendfile()
would reduce the overhead here.I'd also like to have a general high-level
RequestHandler.send_file(file_path, content_type=None)
method for this case that theStaticFileHandler
would call, but that other user code could conveniently use as well. Ifsendfile()
is not available, it would simply fall back to forwarding chunks, but user code wouldn't have to care any more how exactly it works on the current system.The text was updated successfully, but these errors were encountered: