-
-
Notifications
You must be signed in to change notification settings - Fork 345
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
Steal anyio's create_tcp_server #982
Comments
That's basically trio's That said, I think this design is actually a mistake, and we should refactor the
This is harder to fix than you might think! It's non-trivial to define the operation "accept a connection from exactly one of several listening sockets, whichever is available first". It requires an internal buffer holding connections that have been accepted but not yet passed to the user, or making This is also why trio has this awkward convention of passing around lists-of- The other reasons why I'm not too excited about telling people to write their own
I guess the counter-argument would be if you need to customize the actual accept loop somehow, e.g.
My impression is that in practice, if you want to limit incoming connections then it's better to do that based on (a) some kind of global measure of server load, not just what one socket accept loop can see, (b) by accepting connections and then immediately closing them (b/c otherwise the clients just keep hammering you trying to get in, and the connections you do accept are always stale). But, I haven't actually implemented this or even thought about it that much; I definitely don't know what the code would look like :-). Is this something you do? Can you say more about how you do it? |
If somebody floods the current accept loop, which unconditionally starts each connection in a separate task, I'd need a special handler_nursery that limits the rate of task creation. That's a lot more complicated than modifying an Another point to consider is that traditional sync code basically has no choice but to do a while-accept-fork loop. The fact that opening a server socket on Trio suddenly gives you a list of Maybe the |
I have trouble figuring out how seriously Trio should take this. DoS is a real thing and yeah, DoS mitigation is all about rejecting as early and as cheaply as possible. But like... if you have a non-trivial need for DoS mitigation, then you need to go way way way beyond worrying about Trio task spawning overhead. Anyway, if it turns out to be important, then we can certainly discuss how to add some kind of rate limiting logic to our TCP listener. And if someone is in desperate need and can't wait for a Trio release, then as a temporary measure they can always copy/paste our TCP listener implementation and hack it – it doesn't have any special integration with Trio's internals. And IMO doing rate limiting in a way that's actually useful is probably going to be a pretty complicated topic, so we shouldn't try to guess at how to do it until we have some real-world experience to look at. So I think this can be closed? |
anyio's TCP server wrapper is used like this:
IMHO this is a more trio-ish interface than
trio.serve_tcp
because you instead of passing what amounts to a callback to something that doesn't return, you have clear flow of control and can start a new thread (or not) on your own, which is a good idea when you need to limit the server's connection rate.anyio's implementation isn't as nice as we'd like because it only uses one socket instead of binding to every address the parameters tell it to, but that should be fixable.
The text was updated successfully, but these errors were encountered: