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

Log shutdown gracefully #428

Merged
merged 4 commits into from
Oct 7, 2021
Merged

Conversation

mjip
Copy link
Contributor

@mjip mjip commented Oct 3, 2021

Closes #427

@beorn7

Signed-off-by: mjip <marie.payne@hotmail.ca>
@mjip mjip force-pushed the issue-427_log_gracefully branch from 0a1e274 to 25de04b Compare October 3, 2021 19:03
@beorn7
Copy link
Member

beorn7 commented Oct 4, 2021

Thanks for your contribution.

Unfortunately, this doesn't work as intended. The way the graceful shotdown is implemented right now is to close the socket. After that, web.Serve returns with on error (something like accept tcp [::]:9091: use of closed network connection).

If you try out and run the code with your PR, then hit CTRL-C, you will still see the error-level log message.

Signed-off-by: mjip <marie.payne@hotmail.ca>
@mjip
Copy link
Contributor Author

mjip commented Oct 5, 2021

Thanks for picking that up! I added a check on the error message- unfortunately, the maintainers of the net package decided against exporting the errClosing error for use of closed network connections, so I couldn't check the returned error type- golang/go#4373 I also added a comment for context about this change.

@beorn7
Copy link
Member

beorn7 commented Oct 5, 2021

Hmm, I think relying on a certain substring in the error message is very brittle.

I'm not really an expert when it comes to HTTP serving in Go, but I assume the real problem is that we bluntly call l.Close() here:

l.Close()

I have now done a bit of research, and my impression is that we should store a pointer to the http.Server in a variable and give it to the closeListenerOnQuit goroutine. The server is created here:

err = web.Serve(l, &http.Server{Addr: *listenAddress, Handler: mux}, *webConfig, logger)

Then, instead of calling l.Close(), we could call http.Server.Shutdown. Which has two advantages: First, the error returned is now the exported http.ErrServerClosed. Second, we got an actual graceful shutdown for free, so we can get rid of this weird code:

pushgateway/main.go

Lines 200 to 203 in 079d8d8

// To give running connections a chance to submit their payload, we wait
// for 1sec, but we don't want to wait long (e.g. until all connections
// are done) to not delay the shutdown.
time.Sleep(time.Second)

The reason why things were done in this weird way is that it is really old code. The http.Server.Shutdown method was only added in Go1.8, and this Pushgateway code predates that Go version.

Does that make any sense?

Signed-off-by: mjip <marie.payne@hotmail.ca>
@mjip
Copy link
Contributor Author

mjip commented Oct 6, 2021

Your suggestion made sense to me, and I prefer it as well. Let me know if this is what you had in mind.

Copy link
Member

@beorn7 beorn7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks perfect. Thank you very much for removing this old wart.

I just have a tiny bit of nitpicking about a doc comment.

main.go Outdated
go shutdownServerOnQuit(server, quitCh, logger)
err = web.Serve(l, server, *webConfig, logger)

// In the case of a shutdown, log gracefully
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: End sentence with a period.

And, even more nitpicking, "log gracefully" might not really nail it. How about "In the case of a graceful shutdown, do not log the error."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies- I did read the Go Code Review Comments document, but forgot about that convention. This has been changed.

Signed-off-by: mjip <marie.payne@hotmail.ca>
Copy link
Member

@beorn7 beorn7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks perfect. Thank you very much.

@beorn7 beorn7 merged commit 92c8d1e into prometheus:master Oct 7, 2021
@mjip mjip deleted the issue-427_log_gracefully branch October 7, 2021 13:51
@yejumihoutao
Copy link

Hello dear,sorry for desturbing you.
Are there any recent release that include this change?
@beorn7

@beorn7
Copy link
Member

beorn7 commented Oct 11, 2021

@yejumihoutao There hasn't been a lot happening since the last release. But it is quite long ago (1.4.1 happened in May), so I'll cut 1.4.2. Please review #432.

@yejumihoutao
Copy link

@beorn7
ok,thank you for answering me.

thinker0 added a commit to thinker0/pushgateway that referenced this pull request Mar 20, 2022
* master: (30 commits)
  Update common Prometheus files
  Update common Prometheus files
  Update common Prometheus files
  Bump Go version to 1.17
  Update common Prometheus files
  Update common Prometheus files
  Update common Prometheus files
  Cut v1.4.2
  Update dependencies
  Update build tags to new style
  Log shutdown gracefully (prometheus#428)
  Simplify and update the issue template
  Update common Prometheus files
  go.mod: Update dependencies
  Replace go-kit/kit with go-kit/log
  Update common Prometheus files
  Cut v1.4.1
  Fix spelling and comment
  Fix spelling in test
  Fix issue where labels aren't persisted when draining
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Avoid an error level warning upon graceful shutdown
3 participants