Skip to content

Commit

Permalink
jsonrpc: Use process ctx as request ctx parent.
Browse files Browse the repository at this point in the history
This ensures that the context of in-flight RPC requests is cancelled
when the dcrwallet process context is cancelled.
  • Loading branch information
jholdstock committed Oct 14, 2024
1 parent 1e85686 commit 01090e0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 5 deletions.
2 changes: 1 addition & 1 deletion dcrwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func run(ctx context.Context) error {
//
// Servers will be associated with a loaded wallet if it has already been
// loaded, or after it is loaded later on.
gRPCServer, jsonRPCServer, err := startRPCServers(loader)
gRPCServer, jsonRPCServer, err := startRPCServers(ctx, loader)
if err != nil {
log.Errorf("Unable to create RPC servers: %v", err)
return err
Expand Down
11 changes: 9 additions & 2 deletions internal/rpc/jsonrpc/server.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2017-2019 The Decred developers
// Copyright (c) 2017-2024 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -91,13 +91,20 @@ func jsonAuthFail(w http.ResponseWriter) {

// NewServer creates a new server for serving JSON-RPC client connections,
// both HTTP POST and websocket.
func NewServer(opts *Options, activeNet *chaincfg.Params, walletLoader *loader.Loader, listeners []net.Listener) *Server {
func NewServer(ctx context.Context, opts *Options, activeNet *chaincfg.Params, walletLoader *loader.Loader, listeners []net.Listener) *Server {
serveMux := http.NewServeMux()
const rpcAuthTimeoutSeconds = 10
server := &Server{
httpServer: http.Server{
Handler: serveMux,

// Use the provided context as the parent context for all requests
// to ensure handlers are able to react to both client disconnects
// as well as shutdown via the provided context.
BaseContext: func(l net.Listener) context.Context {
return ctx
},

// Timeout connections which don't complete the initial
// handshake within the allowed timeframe.
ReadTimeout: time.Second * rpcAuthTimeoutSeconds,
Expand Down
4 changes: 2 additions & 2 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func generateClientKeyPair(caPriv any, ca *x509.Certificate) (cert, key []byte,
return cert, key, nil
}

func startRPCServers(walletLoader *loader.Loader) (*grpc.Server, *jsonrpc.Server, error) {
func startRPCServers(ctx context.Context, walletLoader *loader.Loader) (*grpc.Server, *jsonrpc.Server, error) {
var jsonrpcAddrNotifier jsonrpcListenerEventServer
var grpcAddrNotifier grpcListenerEventServer
if cfg.RPCListenerEvents {
Expand Down Expand Up @@ -367,7 +367,7 @@ func startRPCServers(walletLoader *loader.Loader) (*grpc.Server, *jsonrpc.Server
TicketSplitAccount: cfg.TicketSplitAccount,
Dial: cfg.dial,
}
jsonrpcServer = jsonrpc.NewServer(&opts, activeNet.Params, walletLoader, listeners)
jsonrpcServer = jsonrpc.NewServer(ctx, &opts, activeNet.Params, walletLoader, listeners)
for _, lis := range listeners {
jsonrpcAddrNotifier.notify(lis.Addr().String())
}
Expand Down

0 comments on commit 01090e0

Please sign in to comment.