rpcclient: add context.Context support for HTTP POST mode#2506
rpcclient: add context.Context support for HTTP POST mode#2506seeforschauer wants to merge 2 commits intobtcsuite:masterfrom
Conversation
Add SendCmdWithContext and GetBlockCountWithContext methods that propagate a context.Context to the underlying HTTP request. This allows callers to cancel or timeout individual RPC calls. Changes: - Add ctx field to jsonRequest struct - Use http.NewRequestWithContext in handleSendPostMessage - Respect context cancellation during retry backoff - Add SendCmdWithContext to Client - Add GetBlockCountWithContext as the first context-aware method - Existing methods are unchanged (non-breaking) Fixes btcsuite#2499
| return c.GetBlockCountAsync().Receive() | ||
| } | ||
|
|
||
| // GetBlockCountWithContext is the context-aware variant of |
There was a problem hiding this comment.
Alternatively, we could update all the methods to accept a context param, but via a functional option. This would break any interfaces created off the client, be direct callers would still compile.
There was a problem hiding this comment.
That would be a larger diff tho, so perhaps we'll land this one extension for now, then return to this later.
There was a problem hiding this comment.
Like this direction a lot — CallOption would avoid the WithContext method explosion across 100+ methods and is extensible for future options. Happy to do it as a follow-up PR once this one lands.
rpcclient/context_test.go
Outdated
|
|
||
| // TestGetBlockCountWithContext_Success verifies that the context- | ||
| // aware GetBlockCountWithContext returns the correct block height. | ||
| func TestGetBlockCountWithContext_Success(t *testing.T) { |
There was a problem hiding this comment.
We could camel case everywhere, including tests.
There was a problem hiding this comment.
Done — all test names use camelCase now.
rpcclient/infrastructure.go
Outdated
| // The context is used to cancel the underlying HTTP request in | ||
| // HTTP POST mode. In websocket mode the context is currently | ||
| // ignored. The returned channel delivers the response. | ||
| func (c *Client) SendCmdWithContext( |
There was a problem hiding this comment.
This duplicates SendCmd, let's refactor such that SendCmdWithContext can just call `SendCmd, but pass in the context from the user.
There was a problem hiding this comment.
Done — SendCmd now delegates to SendCmdWithContext(context.Background(), cmd). Single implementation.
|
|
||
| case <-c.shutdown: | ||
| return | ||
|
|
There was a problem hiding this comment.
Above when we call c.httpClient.Do(httpReq), we should check the context error, as perhaps we should bail right there instead of retrying again.
There was a problem hiding this comment.
Done — added reqCtx.Err() check right after httpClient.Do. If context is cancelled, we bail out immediately instead of entering the backoff/retry path.
Refactor SendCmd to delegate to SendCmdWithContext instead of duplicating the marshalling logic. SendCmdWithContext is now the single implementation; SendCmd passes context.Background(). Add a context error check after httpClient.Do in the retry loop so a cancelled context bails out immediately instead of retrying. Use camelCase for test function names.
Change Description
Add
context.Contextsupport to rpcclient's HTTP POST mode, allowing callers to cancel or timeout individual RPC calls. Fixes #2499.Currently, rpcclient methods like
GetBlockCount()don't accept a context, which means callers have no way to cancel or set deadlines on individual RPC calls. In HTTP POST mode,handleSendPostMessageuseshttp.NewRequestwithout context, and the 10-retry loop doesn't respect external cancellation.Changes
ctxfield tojsonRequeststructhttp.NewRequestWithContextinhandleSendPostMessagewhen ctx is setselectonreqCtx.Done())SendCmdWithContext(ctx, cmd)toClientGetBlockCountWithContext(ctx)as the first context-aware method variantDesign decisions
SendCmdWithContextmirrorsSendCmdwith an added ctx parameterctxis nil (e.g., from existingSendCmdcallers),context.Background()is used as fallback*WithContextmethods for other RPC calls can be added incrementally in follow-up PRsSteps to Test
Pull Request Checklist
Testing
Code Style and Documentation