-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: Request context is not canceled when Server.WriteTimeout
is reached
#59602
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
Comments
note there's already TimeoutHandler https://pkg.go.dev/net/http#TimeoutHandler |
@seankhliao thanks for pointing to the
In my case I have a handler that basically does:
In this case what I need is the request context to be cancelled on timeout to abort the expensive and potentially destructive database calls. During the database calls I typically don't write any response data, so I would not notice that the |
It does cancel the request context |
Ah thanks for pointing that out, I guess that should be added to the docs. The general question of when and why to use
To me it looks like one has to use the |
I think But really the server should also cancel the request context for other handlers (not registered through |
Perhaps it would make sense to cancel the request context when the write timeout is exceeded, since it is no longer possible for the handler to respond after that point. I'm not certain how practical this is to change at this point. The
This does not include when the read or write timeout on a request is exceeded. |
Sharing some findings for people reading this issue trying to figure out when/how to configure Most situations would probably require using
As a result, One may configure As a side note, the "native" Last, the implementation of More details and links to related code: https://stackoverflow.com/a/79269487/6355435 |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
Client side: all requests are cancelled latest after the write timeout, why wait until the handler is done to not receive the result?
Handler side:
r.Context()
is cancelled, so it can stop handling because the result is not returned anywayI have seen #21389 which is kinda related, but not the same issue. I do understand that
w.Write()
does not immediately return an error because of buffering. I would expect the request context to be canceled immediately though.What did you see instead?
Client: request took 1s, although the write timeout is 500ms
Handler: no way to tell whether the timeout was triggered, potentially expensive or destructive work continues
As is, I don't understand the use of
WriteTimeout
at all. It seems there is no effect, except for maybe big responses that might already be partially received by the client (see traefik/traefik#9191 (comment)).I don't think this is a duplicate of #23262 because I see the behavior also when closing the body immediately.
Workaround
It seems pretty simple to just write a middleware that wraps the request context with a timeout:
cc @alnr
The text was updated successfully, but these errors were encountered: