-
Notifications
You must be signed in to change notification settings - Fork 107
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
Options for safely handling slow clients #604
Comments
To address this issue, we will likely need to add support for per-method timeouts that are specified via an option (which can apply different values to different methods via conditional options). This new option can only work with Due to a recently-fixed panic bug (related to use of There are two possible uses for timeouts:
For the former case, having separate read and write timeouts is not as useful since a single timeout is effectively establishing a bound on the entire RPC duration. But for the latter case, separate read and write timeouts is likely very useful: for a long-lived stream where logic is client-initiated, the write timeout (to send a message) might be much shorter than the read timeout (which must include the idle wait time between requests). Initially, we think a new option that can satisfy the first case above is adequate. And we'd leave the door open for future options to accommodate the second case. These options (or analogous ones) might be interesting as client-side options, too. So it might be nice to be able to declaratively define timeouts that are automatically applied to an outbound RPC. And for the second case above, it would effectively allow per-receive and per-send timeouts, which would also be nice to have in a streaming client. |
Currently, slow clients can tie up server resources, as the server code is blocked on reading request data or writing response data. For server-to-server workloads, this is not usually a big concern. But when services are exposed to external, untrusted clients, it can pose an abuse vector. Malicious clients could exploit this to cause a DoS; non-malicious, slow clients (like mobile clients with very poor signal) could lead to operational issues, like excessive resource utilization.
The
http.Server
provides numerous options that Connect servers should use to help with abuse prevention -- in particular theReadTimeout
,ReadHeaderTimeout
, andWriteTimeout
fields.However, these are often inappropriate for RPC traffic, which could be a mix of fast and slow endpoints. In particular, there are classes of streaming endpoints that intend to be long-lived, often with long delays in between messages (subscription/notification endpoints). Since the above configuration is server-wide, one must then choose one of:
An ideal solution is one where the timeout can be configured per endpoint. That way, long-lived streaming endpoints can be configured with a very long (or even no) timeout. Other endpoints can have a reasonably low timeout, which will allow a slow client to be detected and the request to fail faster.
Implementing this, however, requires the use of new-as-of-Go-1.20
http.ResponseController
, which allows setting read and write deadlines on a per-request basis. Ideally, the Connect runtime would surface some configuration for per-endpoint timeouts and then apply them on a per-request basis using aResponseController
.The text was updated successfully, but these errors were encountered: