mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
Make shutdown delay to be conditional and off by default
This commit is contained in:
parent
d64b9526db
commit
8b06db6722
7 changed files with 31 additions and 16 deletions
|
|
@ -183,6 +183,7 @@ var (
|
|||
utils.AllowUnprotectedTxs,
|
||||
utils.BatchRequestLimit,
|
||||
utils.BatchResponseMaxSize,
|
||||
utils.ShutdownDelay,
|
||||
}
|
||||
|
||||
metricsFlags = []cli.Flag{
|
||||
|
|
|
|||
|
|
@ -760,6 +760,12 @@ var (
|
|||
Value: node.DefaultConfig.BatchResponseMaxSize,
|
||||
Category: flags.APICategory,
|
||||
}
|
||||
ShutdownDelay = &cli.DurationFlag{
|
||||
Name: "shutdown-delay",
|
||||
Usage: "Sets a delay between receiving SIGTERM and shutting down the node",
|
||||
Value: node.DefaultConfig.ShutdownDelay,
|
||||
Category: flags.APICategory,
|
||||
}
|
||||
|
||||
// Network Settings
|
||||
MaxPeersFlag = &cli.IntFlag{
|
||||
|
|
@ -1204,6 +1210,10 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
|
|||
if ctx.IsSet(BatchResponseMaxSize.Name) {
|
||||
cfg.BatchResponseMaxSize = ctx.Int(BatchResponseMaxSize.Name)
|
||||
}
|
||||
|
||||
if ctx.IsSet(ShutdownDelay.Name) {
|
||||
cfg.ShutdownDelay = ctx.Duration(ShutdownDelay.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// setGraphQL creates the GraphQL listener interface string from the set
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
|
@ -211,6 +212,9 @@ type Config struct {
|
|||
EnablePersonal bool `toml:"-"`
|
||||
|
||||
DBEngine string `toml:",omitempty"`
|
||||
|
||||
// ShutdownDelay is the delay between receiving SIGTERM and shutting down the node.
|
||||
ShutdownDelay time.Duration `toml:",omitempty"`
|
||||
}
|
||||
|
||||
// IPCEndpoint resolves an IPC endpoint based on a configured value, taking into
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
|
|
@ -73,6 +74,7 @@ var DefaultConfig = Config{
|
|||
NAT: nat.Any(),
|
||||
},
|
||||
DBEngine: "", // Use whatever exists, will default to Pebble if non-existent and supported
|
||||
ShutdownDelay: 0 * time.Second,
|
||||
}
|
||||
|
||||
// DefaultDataDir is the default data directory to use for the databases and other
|
||||
|
|
|
|||
|
|
@ -150,10 +150,10 @@ func New(conf *Config) (*Node, error) {
|
|||
}
|
||||
|
||||
// Configure RPC servers.
|
||||
node.http = newHTTPServer(node.log, conf.HTTPTimeouts)
|
||||
node.httpAuth = newHTTPServer(node.log, conf.HTTPTimeouts)
|
||||
node.ws = newHTTPServer(node.log, rpc.DefaultHTTPTimeouts)
|
||||
node.wsAuth = newHTTPServer(node.log, rpc.DefaultHTTPTimeouts)
|
||||
node.http = newHTTPServer(node.log, conf.HTTPTimeouts, conf.ShutdownDelay)
|
||||
node.httpAuth = newHTTPServer(node.log, conf.HTTPTimeouts, conf.ShutdownDelay)
|
||||
node.ws = newHTTPServer(node.log, rpc.DefaultHTTPTimeouts, conf.ShutdownDelay)
|
||||
node.wsAuth = newHTTPServer(node.log, rpc.DefaultHTTPTimeouts, conf.ShutdownDelay)
|
||||
node.ipc = newIPCServer(node.log, conf.IPCEndpoint())
|
||||
|
||||
return node, nil
|
||||
|
|
|
|||
|
|
@ -70,11 +70,12 @@ type httpServer struct {
|
|||
timeouts rpc.HTTPTimeouts
|
||||
mux http.ServeMux // registered handlers go here
|
||||
|
||||
mu sync.Mutex
|
||||
server *http.Server
|
||||
listener net.Listener // non-nil when server is running
|
||||
ready bool
|
||||
shutdownWG sync.WaitGroup // WG to wait for shutdown
|
||||
mu sync.Mutex
|
||||
server *http.Server
|
||||
listener net.Listener // non-nil when server is running
|
||||
ready bool
|
||||
shutdownWG sync.WaitGroup // WG to wait for shutdown
|
||||
shutdownDelay time.Duration
|
||||
|
||||
// HTTP RPC handler things.
|
||||
httpConfig httpConfig
|
||||
|
|
@ -94,13 +95,10 @@ type httpServer struct {
|
|||
|
||||
const (
|
||||
shutdownTimeout = 5 * time.Second
|
||||
// give pending requests stopPendingRequestTimeout the time to finish when the server is stopped
|
||||
// if readiness probe period is 5 seconds, this is enough time for health check to be triggered
|
||||
stopPendingRequestTimeout = 7 * time.Second
|
||||
)
|
||||
|
||||
func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts) *httpServer {
|
||||
h := &httpServer{log: log, timeouts: timeouts, handlerNames: make(map[string]string)}
|
||||
func newHTTPServer(log log.Logger, timeouts rpc.HTTPTimeouts, shutdownDelay time.Duration) *httpServer {
|
||||
h := &httpServer{log: log, timeouts: timeouts, handlerNames: make(map[string]string), shutdownDelay: shutdownDelay}
|
||||
|
||||
h.httpHandler.Store((*rpcHandler)(nil))
|
||||
h.wsHandler.Store((*rpcHandler)(nil))
|
||||
|
|
@ -282,7 +280,7 @@ func (h *httpServer) stop() {
|
|||
h.shutdownWG = sync.WaitGroup{}
|
||||
h.shutdownWG.Add(1)
|
||||
h.ready = false
|
||||
time.AfterFunc(stopPendingRequestTimeout, func() {
|
||||
time.AfterFunc(h.shutdownDelay, func() {
|
||||
defer h.mu.Unlock()
|
||||
h.doStop()
|
||||
h.shutdownWG.Done()
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ func createAndStartServer(t *testing.T, conf *httpConfig, ws bool, wsConf *wsCon
|
|||
if timeouts == nil {
|
||||
timeouts = &rpc.DefaultHTTPTimeouts
|
||||
}
|
||||
srv := newHTTPServer(testlog.Logger(t, log.LvlDebug), *timeouts)
|
||||
srv := newHTTPServer(testlog.Logger(t, log.LvlDebug), *timeouts, 0*time.Second)
|
||||
assert.NoError(t, srv.enableRPC(apis(), *conf))
|
||||
if ws {
|
||||
assert.NoError(t, srv.enableWS(nil, *wsConf))
|
||||
|
|
|
|||
Loading…
Reference in a new issue