Description
I've been exploring paths for setting timeouts for both HTTP servers and clients. My goal is specific timeouts at different stages in the request/response lifecycle. This is more pronounced on HTTP1, but there is some use with HTTP2 as well.
Since timeouts are presently set via Endpoints, and those aren't necessarily specific to the protocol client/server to be used, my thought is to add a handful of specific hooks into the Connection and related classes. This would avoid adding a bunch of *_timeout
settings all over.
These hooks would likely just be empty methods (or a simple yield
) in the default implementation. Then the idea would be that an app could inherit from the relevant Server or Client, or add a mixin, and then modify timeout=
directly.
I could also see such hooks being used apart from timeouts, for example: metrics gathering (requests, bytes, etc).
So far, here are the hooks I'm thinking of:
- h1: after a new request has been started (between GET line and headers) (Server)
- h1: after a request has been sent, before response headers received (Client)
- h1: after a response has been sent and waiting for a new request (keepalive) (Server)
- h2: after the connection preface is sent/received (Client/Server)
I've read some of the other issues discussing timeouts. They seem to partly address Client usage, but less so Server usage. Where with_timeout
works, it would remain the recommended approach. I see hooks like this being complementary and not a replacement for that.
I'm happy to prepare a PR for this, but I wanted to first check and see if it goes in a direction you're comfortable with?
Open to any thoughts, suggestions, or questions as well, of course.
Semi-related, but I've also considered an error-handling hook(s) to help intercept various exceptions before they result in "task ended with unhandled exception". Would that seem appropriate? Such a hook could be used to silence such errors, count them for metrics, etc. Or, would there be any interest in PRs to just silently rescue some of those if a hook seems like too much?
PS: Thanks so much for the incredibly useful gem (and the whole async ecosystem)!