Possible solution for IOSelectorsException: "Maximum number of descriptors is exhausted!"
termermc opened this issue · 1 comments
Hi, I've been using your library and a few others with some stress testing software and I've noticed one issue that no server seems to handle, which is file descriptor exhaustion. Currently, when overloading the server with too many connections (I tested with 10k connections on Arch Linux), this exception is raised and the entire application crashes, regardless of whether I'm using threads or not, because the exception is being raised in the event loop.
I did some local testing, and wrapping the selector.registerHandle
call within the acceptClient
template with an empty try/except for IOSelectorsException resolves this issue. I tested whether it was leaking any memory under ORC as a result, and it was not. This allows the server to be exposed without crashing from thread exhaustion. The current state now allows a DoS attack by opening too many connections on the server, which is obviously a hazard if you're exposing the server to the internet.
The reason I didn't send in a PR for this and instead opened an issue is that this seems like a potentially hacky fix. It does prevent errors like this from crashing the server and instead let them be silently ignored and continue execution, however it may reduce visibility of other IOSelectorsException instances that are unrelated to this problem. AsyncHttpServer opts to check whether it's safe to accept a client with shouldAcceptRequest
, but this proc is not threadsafe and will lead of to IOSelectorException at unexpected times when using multiple threads, which I have personally experienced. All it takes is a file descriptor being taken in between the time of the check and the time of accepting the client.
I believe silently handling IOSelectorsException is the most foolproof way to handle this issue, but it does have the concern that I mentioned aboved. Let me know what you think about this and any suggestions you may have. If you believe my solution is suitable, I can send in a PR. Otherwise, let's talk. I think this is a very important issue because it determines whether you can safely expose httpx to the internet or not.
Thanks, and kudos to providing a library that performs much better (over 300x faster in my benchmarks) than AsyncHttpServer while still being usable.
@termermc Hello, I appreciate your inputs. I doubt that I'm satisfied with the current async runtime, which discourages me from improving it. If it works behind nginx, it is good enough for its purpose. Though, we probably should implement/wrap a new HTTP server based on io_uring
on Linux. My time is used up on contributing to the Nim compiler. In my free time, I might focus on https://github.com/iocrate/org and https://github.com/iocrate/thinknim .