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

use native Go HTTP/2 server setup and graceful shutdown #59

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

khatibomar
Copy link

@khatibomar khatibomar commented Mar 8, 2025

Replace manual HTTP/2 connection handling with native HTTP server setup using HTTP/2 protocols. This change simplifies the server code and provides better shutdown handling through a proper server.Shutdown call. Also updates Go version to 1.24.

The old implementation had a bug where once you start server you can't shut it down, even when context cancels, so it hangs the client code, indefinitely.

Replace manual HTTP/2 connection handling with native HTTP server setup using
HTTP/2 protocols. This change simplifies the server code and provides better
shutdown handling through a proper server.Shutdown call. Also updates Go
version to 1.24.

The old implementation had a bug where once you start server you can't
shut it down, even when context cancels, so it hand the client code,
indefinitely.
this part of the code is redudant
return fmt.Errorf("failed to accept connection: %w", err)
go func() {
<-ctx.Done()
if err := server.Shutdown(context.Background()); err != nil {
Copy link
Author

Choose a reason for hiding this comment

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

here, I am not sure if doing a timeout of 30 seconds for example is better than leaving it trying to shutdown for ever.

Copy link
Author

Choose a reason for hiding this comment

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

shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

if err := server.Shutdown(shutdownCtx); err != nil {
    slog.Error("Server shutdown error", "error", err)
}

Add a 30 second timeout to the server shutdown context to prevent
hanging indefinitely during shutdown. This ensures the server shuts down
gracefully within a reasonable time frame.
@slinkydeveloper slinkydeveloper self-requested a review March 10, 2025 07:49
Copy link
Contributor

@slinkydeveloper slinkydeveloper left a comment

Choose a reason for hiding this comment

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

I think this patch is valid, although I'm not sure is a good idea to bump minimum golang required version to 1.24 right now, as it might break some users programs. So I would keep this on hold and wait a bit before merging it.

@khatibomar
Copy link
Author

	errChan := make(chan error, 1)

	go func(ctx context.Context) {
		for {
			con, err := listener.Accept()
			if err != nil {
				errChan <- fmt.Errorf("failed to accept connection: %w", err)
				return
			}

			go h2server.ServeConn(con, opts)
		}
	}(ctx)

	select {
	case err := <-errChan:
		return err
	case <-ctx.Done():
		return listener.Close()
	}

we can do that also for the old code, I think that connections will stay open because we are not doing con.Close(), so if the Start caller didn't wait on them and processed killed they will get force closed. So not really graceful.

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.

2 participants