-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
net/http: add built-in graceful shutdown support to Server #4674
Comments
Sounds familiar... http://tomayko.com/writings/unicorn-is-unix |
You mention a few separate issues. 1. net/http doesn't offer a convenience function for net.Listen followed by http.Serve. 2. closing the underlying net.Listener doesn't shut down the http.Serve loop (because of a race condition?) 3. there's no mechanism to gracefully shut down an http.Serve loop, waiting for any in-flight requests to complete I think the second point is a priority. The first doesn't seem very interesting to me. The third point is a feature that we should explore further. This issue should be about the third point only. Can you please file issues for the other two points? I would especially like as much information as you have about the second point. Thanks Status changed to Accepted. |
Comment 5 by patrick.allen.higgins: I created issue #4737, which I believe is related to the second point. |
Comment 16 by r@rcrowley.org: After making some headway on this problem outside the standard library I decided to take a stab at it in net/http itself. https://golang.org/cl/67730046/ |
Sent out https://golang.org/cl/69260044/ for discussion. It should be sufficient to implement shutdown outside of net/http, with varying levels of gracefulness. Labels changed: added release-go1.3maybe, removed priority-later, release-none. |
Also sent out https://golang.org/cl/69670043 for disabling keep-alives (sending "Connection: close" in Handlers) |
This issue was updated by revision 67b8bf3. This allows for all sorts of graceful shutdown policies, without picking a policy (e.g. lameduck period) and without adding lots of locking to the server core. That policy and locking can be implemented outside of net/http now. LGTM=adg R=golang-codereviews, josharian, r, adg, dvyukov CC=golang-codereviews https://golang.org/cl/69260044 |
This issue was updated by revision 916682e. LGTM=adg, josharian R=adg, josharian, r CC=golang-codereviews https://golang.org/cl/69670043 |
This issue was updated by revision 7124ee5. LGTM=bradfitz R=bradfitz CC=golang-codereviews https://golang.org/cl/70410044 Committer: Brad Fitzpatrick |
Status update: Go 1.3 will have all the necessary net/http changes (Server.ConnState and Server.SetKeepAlivesEnabled) for other people to implement graceful shutdown properly, outside the net/http package. But because there are various policy questions of how quickly and how politely to shut down a server, we're going to refrain from unilaterally making that policy decision now (in the form of e.g. a Server.Close method) and instead make people pick their own policy for now. It's possible in the future (after some experience using different shutdown strategies in Go 1.3) we might see the common patterns and add a convenience shutdown/close method, perhaps with a timeout or options, once we know what the set of options are. So punting this to Go 1.4, even though most of the work will already be in Go 1.3. Labels changed: added release-go1.4, removed release-go1.3maybe. |
Any progress on this issue? |
No, but I think a plan has started to form. It'll be a blocking: func (s *Server) Shutdown(context.Context) error {}
func (s *Server) Close() error {} Where the first one is graceful and takes a context (so you can abort early if it's taking too long), and the second one is forced and immediate. It would only return an The Go 1.8 dev tree closes Sunday night, so I'll mark this as Go 1.9. |
Is there actually any point in implementing io.Closer? I don't think that an HTTP server really falls into that category, or that one would want to use it interchangeably with other io.Closers |
@dominikh Given that Listener.Close returns an error, wouldn't you want to pass that on? |
@cespare Good point. I was thrown off by Brad saying that it would always return nil. |
"but would basically always return nil" :-) Yeah, passing on the net.Listener(s)' return value makes sense. |
CL https://golang.org/cl/32329 mentions this issue. |
I managed to implement this in a few hours before the freeze, and people have been wanting this forever, so Go 1.8 it is. |
CL https://golang.org/cl/32412 mentions this issue. |
This adds support for gracefully shutting down the Server, including sending a GOAWAY frame to clients and shutting down when things are idle. For now this support is only when integrated with the standard library's Server. A future change could export some of this. Updates golang/go#4674 Change-Id: I78cd4f58ca529bf9d149054f929d9089e7685875 Reviewed-on: https://go-review.googlesource.com/32412 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
I may be missing something, but it looks like hijacked connections are just removed from the tracked connections and if I'm not mistaken WebSockets hijack the connection; so my question is, with this change how would one ensure graceful shutdown of connections including WebSockets? It appears that they would be interrupted/closed after all normal http idle connections are completed and the process ends. I've only been able to do it using a custom listener that keeps track of the connections created and closed, ConnState for keeping track of idle KeepAlive connections all bundled in a library, kms, that exposes a ShutdownInitialized channel that WebSockets, and anything else, can use to gracefully shut themselves down with. |
@joeybloggs, filed #17721 |
@bradfitz out of curiosity along with the current implementation, why not provide a then server.Shutdown() can wait using the WaitGroup(), context and Timeout. It just seems like having graceful shutdown built into net/http that doesn't support some pretty common cases seems incomplete/wrong somehow. |
Let's comment on new issue(s) instead of a closed issue. The new issue(s) can reference this one, and then they'll be cross-linked. Also, it's more constructive (at least for me) if you explain the problematic or desired behavior, and not the implementation. The implementation is generally straight-forward given the requirements. |
this issue has been dragging along since 1.1 |
@rami-dabain, this is a closed issue. This was added to Go 1.8: https://golang.org/doc/go1.8#http_shutdown |
by patrick.allen.higgins:
The text was updated successfully, but these errors were encountered: