Skip to content
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

question: why does the http server still handle request in ServeHTTP after server.Close or server.Shutdown #31438

Closed
pingworld opened this issue Apr 12, 2019 · 5 comments
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@pingworld
Copy link

What version of Go are you using (go version)?

1.10.3

Does this issue reproduce with the latest release?

YES. It happens when we build using go1.12.2.

What operating system and processor architecture are you using (go env)?

go env Output
GOARCH="amd64"
GOBIN=""
GOCACHE=""
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build956601935=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I put some code snippets on here.

What did you expect to see?

The http server will not call "(w *WebSvrImpl) ServeHTTP" after we call "(w *WebSvrImpl) Close()". And the http server should return some special error code. e.g. 404?

What did you see instead?

The http server still returns response with http status code 200 and empty body.

We had known the response with empty body is caused by "(w *WebSvrImpl) ServeHTTP" which will not process when "w.closed.Get()" is true.

But why the net/http framework still call ServeHTTP() when we had called the Close() or Shutdown()?


Thanks for your reply!

@bcmills
Copy link
Contributor

bcmills commented Apr 12, 2019

I put some code snippets on here.

Please summarize the relevant properties of those snippets — they don't compile, and it's not obvious what the elided code does or how that interacts with the call to Close.

Note per https://golang.org/pkg/net/http/#Server.Close:

Close does not attempt to close (and does not even know about) any hijacked connections, such as WebSockets.

Also note that closing a connection does not terminate any associated goroutine running ServeHTTP: those goroutines will continue to run until they decide to return (perhaps as a result of noticing a failed write to the response). In particular, it is possible for the ServeHTTP goroutine to start, then the Close call to execute, and finally the ServerHTTP goroutine to become scheduled and run.

So the details of what those nested servers are actually doing are very important, as are the details about when exactly you expect ServeHTTP to no longer be called.

@bcmills bcmills added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Apr 12, 2019
@pingworld
Copy link
Author

Thanks for your reply.

Please summarize the relevant properties of those snippets — they don't compile, and it's not obvious what the elided code does or how that interacts with the call to Close.

First we create an object of type WebSvrImpl, then call ListenAndServe, now we can recv the http request from client.

Those requests are used for loading some business data from DB.

After serving all the http requests we call Close on such object and stop the whole application.

Then we expect the server will not recv the request from any client.

As you say

Also note that closing a connection does not terminate any associated goroutine running ServeHTTP

we expect that the http.Server should return some error code to indicate it had been stoped during the time we call Close and the end moment of server.

But we still got http request which was handled by ServeHTTP.


Thanks.

@bcmills
Copy link
Contributor

bcmills commented Apr 16, 2019

we expect that the http.Server should return some error code to indicate it had been stoped during the time we call Close and the end moment of server.

Close literally closes the connection. There is no opportunity to return any error code at that point.

If you want the server to shut down gracefully, you can use the Shutdown method. With that approach, you'd need to communicate the start of shutdown to the handlers by whatever mechanism you like (such as canceling a context.Context), and they can report an appropriate error explicitly.

@andybons andybons changed the title why does the http server still handle request in ServeHTTP after server.Close or server.Shutdown question: why does the http server still handle request in ServeHTTP after server.Close or server.Shutdown May 14, 2019
@andybons andybons added this to the Unreleased milestone May 14, 2019
@andybons
Copy link
Member

@pingworld did this adequately answer your question?

@agnivade agnivade added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. and removed WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels May 14, 2019
@pingworld
Copy link
Author

Thanks, we have no other questions! We have solved this problem!

All requests have been processed after waiting for several seconds when close the whole app.

@golang golang locked and limited conversation to collaborators May 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

5 participants