-
-
Notifications
You must be signed in to change notification settings - Fork 62
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
Switch internal agent selector to improve throughput #17
Comments
It appears that this cannot be done on Windows without modifying libcurl to make less assumptions with its socket management. Closing this for now, as it isn't worth the high effort for an unknown amount of efficiency improvement. In particular, IOCP on Windows requires you to use specific read and write functions instead of the standard ones, which libcurl doesn't allow you to configure. |
Re-opened, since we finally have a potential way forward using the excellent polling crate. |
Replace the built-in `select(2)`-based I/O driver with [polling](https://github.com/stjepang/polling), which should deliver noticeably better throughput under high activity, _especially_ on Windows. Fixes #17.
Replace the built-in `select(2)`-based I/O driver with [polling](https://github.com/stjepang/polling), which should deliver noticeably better throughput under high activity, _especially_ on Windows. This implementation took several attempts before I fully understood some of the curl quirks on how it handles sockets; for example, curl will often close sockets before asking them to be de-registered, register and deregister the same file descriptor number between polls (because the OS reused the number), and request sockets to be registered before they are initialized. To handle these quirks this provides a wrapper layer around the polling crate that translates this behavior into something polling can handle. In addition to verifying all the tests pass, I've also run a sort of "soak test" on Linux, Windows, and macOS for 12 hours straight that makes many requests repeatedly in order to weed out potential random errors (I learned of the possible Win32 error code `ERROR_NOT_FOUND (0x490)` this way!). Fixes #17.
libcurl uses
poll(2)
at best case for its selector implementation, and at worst case usesselect(2)
, which can perform rather badly with many concurrent requests. Isahc already performs really well (at least under unix-like systems), but to get maximum possible performance, we should switch away from usingcurl_multi_select()
and switch to using a library that efficiently uses the best selector available on the target system. This should especially aid performance on Windows, where IOCP has far better throughput thanselect(2)
.Initially we investigated using Mio which has many nice benefits, but unfortunately will not work for us since Mio requires ownership of the socket handles and requires all read and write calls to go through Mio. But libcurl is going to read and write to the socket handles directly and we can't change that, so Mio is out.
Sometime after this issue was initially created the polling crate was introduced, which looks very promising and should work for us as an alternative. It has less features than Mio, but frankly we don't need those extra features, and more importantly polling allows us to keep ownership of the socket handles. On Windows it uses wepoll which is a widely accepted readiness-driven wrapper around IOCP that performs well.
Implementation is slow-going, but is on this PR here: #243
The text was updated successfully, but these errors were encountered: