mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
Cleaner shutdown logic
This commit is contained in:
parent
6928ec5d92
commit
40ce7408c4
3 changed files with 25 additions and 8 deletions
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -519,6 +520,7 @@ func (n *Node) stopRPC() {
|
||||||
n.ws.stop()
|
n.ws.stop()
|
||||||
n.httpAuth.stop()
|
n.httpAuth.stop()
|
||||||
n.wsAuth.stop()
|
n.wsAuth.stop()
|
||||||
|
time.Sleep(rpc.StopPendingRequestTimeout)
|
||||||
n.ipc.stop()
|
n.ipc.stop()
|
||||||
n.stopInProc()
|
n.stopInProc()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,11 @@ func (t *httpServerConn) SetWriteDeadline(time.Time) error { return nil }
|
||||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Permit dumb empty requests for remote health-checks (AWS)
|
// Permit dumb empty requests for remote health-checks (AWS)
|
||||||
if r.Method == http.MethodGet && r.ContentLength == 0 && r.URL.RawQuery == "" {
|
if r.Method == http.MethodGet && r.ContentLength == 0 && r.URL.RawQuery == "" {
|
||||||
w.WriteHeader(http.StatusOK)
|
if s.ready {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if code, err := s.validateRequest(r); err != nil {
|
if code, err := s.validateRequest(r); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
@ -36,6 +37,10 @@ const EngineApi = "engine"
|
||||||
type CodecOption int
|
type CodecOption int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// 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 = 6 * time.Second
|
||||||
|
|
||||||
// OptionMethodInvocation is an indication that the codec supports RPC method calls
|
// OptionMethodInvocation is an indication that the codec supports RPC method calls
|
||||||
OptionMethodInvocation CodecOption = 1 << iota
|
OptionMethodInvocation CodecOption = 1 << iota
|
||||||
|
|
||||||
|
|
@ -51,6 +56,7 @@ type Server struct {
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
codecs map[ServerCodec]struct{}
|
codecs map[ServerCodec]struct{}
|
||||||
run atomic.Bool
|
run atomic.Bool
|
||||||
|
ready bool
|
||||||
batchItemLimit int
|
batchItemLimit int
|
||||||
batchResponseLimit int
|
batchResponseLimit int
|
||||||
httpBodyLimit int
|
httpBodyLimit int
|
||||||
|
|
@ -68,6 +74,7 @@ func NewServer() *Server {
|
||||||
// as the services and methods it offers.
|
// as the services and methods it offers.
|
||||||
rpcService := &RPCService{server}
|
rpcService := &RPCService{server}
|
||||||
server.RegisterName(MetadataApi, rpcService)
|
server.RegisterName(MetadataApi, rpcService)
|
||||||
|
server.ready = true
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,15 +191,19 @@ func messageForReadError(err error) string {
|
||||||
// requests to finish, then closes all codecs which will cancel pending requests and
|
// requests to finish, then closes all codecs which will cancel pending requests and
|
||||||
// subscriptions.
|
// subscriptions.
|
||||||
func (s *Server) Stop() {
|
func (s *Server) Stop() {
|
||||||
s.mutex.Lock()
|
log.Debug("RPC server draining pending requests")
|
||||||
defer s.mutex.Unlock()
|
s.ready = false
|
||||||
|
time.AfterFunc(StopPendingRequestTimeout, func() {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
if s.run.CompareAndSwap(true, false) {
|
if s.run.CompareAndSwap(true, false) {
|
||||||
log.Debug("RPC server shutting down")
|
log.Debug("RPC server shutting down")
|
||||||
for codec := range s.codecs {
|
for codec := range s.codecs {
|
||||||
codec.close()
|
codec.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPCService gives meta information about the server.
|
// RPCService gives meta information about the server.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue