node: use atomic.Pointer for rpc handler

This commit is contained in:
Felix Lange 2025-06-16 12:45:35 +02:00
parent fd4e1f83cb
commit 4f468ae488

View file

@ -77,11 +77,11 @@ type httpServer struct {
// HTTP RPC handler things. // HTTP RPC handler things.
httpConfig httpConfig httpConfig httpConfig
httpHandler atomic.Value // *rpcHandler httpHandler atomic.Pointer[rpcHandler]
// WebSocket handler things. // WebSocket handler things.
wsConfig wsConfig wsConfig wsConfig
wsHandler atomic.Value // *rpcHandler wsHandler atomic.Pointer[rpcHandler]
// These are set by setListenAddr. // These are set by setListenAddr.
endpoint string endpoint string
@ -97,9 +97,6 @@ const (
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)}
h.httpHandler.Store((*rpcHandler)(nil))
h.wsHandler.Store((*rpcHandler)(nil))
return h return h
} }
@ -198,7 +195,7 @@ func (h *httpServer) start() error {
func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// check if ws request and serve if ws enabled // check if ws request and serve if ws enabled
ws := h.wsHandler.Load().(*rpcHandler) ws := h.wsHandler.Load()
if ws != nil && isWebsocket(r) { if ws != nil && isWebsocket(r) {
if checkPath(r, h.wsConfig.prefix) { if checkPath(r, h.wsConfig.prefix) {
ws.ServeHTTP(w, r) ws.ServeHTTP(w, r)
@ -207,7 +204,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
// if http-rpc is enabled, try to serve request // if http-rpc is enabled, try to serve request
rpc := h.httpHandler.Load().(*rpcHandler) rpc := h.httpHandler.Load()
if rpc != nil { if rpc != nil {
// First try to route in the mux. // First try to route in the mux.
// Requests to a path below root are handled by the mux, // Requests to a path below root are handled by the mux,
@ -267,14 +264,14 @@ func (h *httpServer) doStop() {
} }
// Shut down the server. // Shut down the server.
httpHandler := h.httpHandler.Load().(*rpcHandler) httpHandler := h.httpHandler.Load()
wsHandler := h.wsHandler.Load().(*rpcHandler) wsHandler := h.wsHandler.Load()
if httpHandler != nil { if httpHandler != nil {
h.httpHandler.Store((*rpcHandler)(nil)) h.httpHandler.Store(nil)
httpHandler.server.Stop() httpHandler.server.Stop()
} }
if wsHandler != nil { if wsHandler != nil {
h.wsHandler.Store((*rpcHandler)(nil)) h.wsHandler.Store(nil)
wsHandler.server.Stop() wsHandler.server.Stop()
} }
@ -322,9 +319,9 @@ func (h *httpServer) enableRPC(apis []rpc.API, config httpConfig) error {
// disableRPC stops the HTTP RPC handler. This is internal, the caller must hold h.mu. // disableRPC stops the HTTP RPC handler. This is internal, the caller must hold h.mu.
func (h *httpServer) disableRPC() bool { func (h *httpServer) disableRPC() bool {
handler := h.httpHandler.Load().(*rpcHandler) handler := h.httpHandler.Load()
if handler != nil { if handler != nil {
h.httpHandler.Store((*rpcHandler)(nil)) h.httpHandler.Store(nil)
handler.server.Stop() handler.server.Stop()
} }
return handler != nil return handler != nil
@ -369,9 +366,9 @@ func (h *httpServer) stopWS() {
// disableWS disables the WebSocket handler. This is internal, the caller must hold h.mu. // disableWS disables the WebSocket handler. This is internal, the caller must hold h.mu.
func (h *httpServer) disableWS() bool { func (h *httpServer) disableWS() bool {
ws := h.wsHandler.Load().(*rpcHandler) ws := h.wsHandler.Load()
if ws != nil { if ws != nil {
h.wsHandler.Store((*rpcHandler)(nil)) h.wsHandler.Store(nil)
ws.server.Stop() ws.server.Stop()
} }
return ws != nil return ws != nil
@ -379,12 +376,12 @@ func (h *httpServer) disableWS() bool {
// rpcAllowed returns true when JSON-RPC over HTTP is enabled. // rpcAllowed returns true when JSON-RPC over HTTP is enabled.
func (h *httpServer) rpcAllowed() bool { func (h *httpServer) rpcAllowed() bool {
return h.httpHandler.Load().(*rpcHandler) != nil return h.httpHandler.Load() != nil
} }
// wsAllowed returns true when JSON-RPC over WebSocket is enabled. // wsAllowed returns true when JSON-RPC over WebSocket is enabled.
func (h *httpServer) wsAllowed() bool { func (h *httpServer) wsAllowed() bool {
return h.wsHandler.Load().(*rpcHandler) != nil return h.wsHandler.Load() != nil
} }
// isWebsocket checks the header of an http request for a websocket upgrade request. // isWebsocket checks the header of an http request for a websocket upgrade request.