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"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -519,6 +520,7 @@ func (n *Node) stopRPC() {
|
|||
n.ws.stop()
|
||||
n.httpAuth.stop()
|
||||
n.wsAuth.stop()
|
||||
time.Sleep(rpc.StopPendingRequestTimeout)
|
||||
n.ipc.stop()
|
||||
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) {
|
||||
// Permit dumb empty requests for remote health-checks (AWS)
|
||||
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
|
||||
}
|
||||
if code, err := s.validateRequest(r); err != nil {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
|
@ -36,6 +37,10 @@ const EngineApi = "engine"
|
|||
type CodecOption int
|
||||
|
||||
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 CodecOption = 1 << iota
|
||||
|
||||
|
|
@ -51,6 +56,7 @@ type Server struct {
|
|||
mutex sync.Mutex
|
||||
codecs map[ServerCodec]struct{}
|
||||
run atomic.Bool
|
||||
ready bool
|
||||
batchItemLimit int
|
||||
batchResponseLimit int
|
||||
httpBodyLimit int
|
||||
|
|
@ -68,6 +74,7 @@ func NewServer() *Server {
|
|||
// as the services and methods it offers.
|
||||
rpcService := &RPCService{server}
|
||||
server.RegisterName(MetadataApi, rpcService)
|
||||
server.ready = true
|
||||
return server
|
||||
}
|
||||
|
||||
|
|
@ -184,15 +191,19 @@ func messageForReadError(err error) string {
|
|||
// requests to finish, then closes all codecs which will cancel pending requests and
|
||||
// subscriptions.
|
||||
func (s *Server) Stop() {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
log.Debug("RPC server draining pending requests")
|
||||
s.ready = false
|
||||
time.AfterFunc(StopPendingRequestTimeout, func() {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
if s.run.CompareAndSwap(true, false) {
|
||||
log.Debug("RPC server shutting down")
|
||||
for codec := range s.codecs {
|
||||
codec.close()
|
||||
if s.run.CompareAndSwap(true, false) {
|
||||
log.Debug("RPC server shutting down")
|
||||
for codec := range s.codecs {
|
||||
codec.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// RPCService gives meta information about the server.
|
||||
|
|
|
|||
Loading…
Reference in a new issue