rpc: add graceful shutdown timeout for HTTP server (#25258)

This change ensures the HTTP server will always terminate within
at most 5s, even when all connections are busy and do not become
idle.

Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
Brion 2022-07-09 03:25:12 +08:00 committed by GitHub
parent ae8ce72022
commit d839515434
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -27,6 +27,7 @@ import (
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
@ -81,6 +82,10 @@ type httpServer struct {
handlerNames map[string]string handlerNames map[string]string
} }
const (
shutdownTimeout = 5 * time.Second
)
func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts) *httpServer { func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts) *httpServer {
h := &httpServer{log: log, timeouts: timeouts, handlerNames: make(map[string]string)} h := &httpServer{log: log, timeouts: timeouts, handlerNames: make(map[string]string)}
@ -261,7 +266,13 @@ func (h *httpServer) doStop() {
h.wsHandler.Store((*rpcHandler)(nil)) h.wsHandler.Store((*rpcHandler)(nil))
wsHandler.server.Stop() wsHandler.server.Stop()
} }
h.server.Shutdown(context.Background()) ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
defer cancel()
err := h.server.Shutdown(ctx)
if err == ctx.Err() {
h.log.Warn("HTTP server graceful shutdown timed out")
h.server.Close()
}
h.listener.Close() h.listener.Close()
h.log.Info("HTTP server stopped", "endpoint", h.listener.Addr()) h.log.Info("HTTP server stopped", "endpoint", h.listener.Addr())