Skip to content

feat(multiclient): adds timeouts to retryWithBackups and dialWithRetry#84

Merged
giogam merged 8 commits intomainfrom
CLD-252/add-a-default-request-timeout-to-multi-client
May 19, 2025
Merged

feat(multiclient): adds timeouts to retryWithBackups and dialWithRetry#84
giogam merged 8 commits intomainfrom
CLD-252/add-a-default-request-timeout-to-multi-client

Conversation

@giogam
Copy link
Contributor

@giogam giogam commented May 15, 2025

This PR enhances the MultiClient implementation by adding timeout support and improving test coverage.

Timeout Handling:

  • Added Timeout and DialTimeout to RetryConfig, with defaults for RPC and dial operations.
  • Updated retryWithBackups and dialWithRetry to use context.WithTimeout, enforcing timeouts for RPC calls and connections.

Context Propagation:

  • All MultiClient methods (SendTransaction, CallContract, etc.) now pass context.Context through to support cancellation and timeouts consistently.

Test Improvements:

  • Added TestMultiClient_dialWithRetry to cover dial timeouts and failure scenarios.
  • Expanded TestMultiClient_retryWithBackups to simulate timeouts and long-running operations using context.

@giogam giogam requested a review from a team as a code owner May 15, 2025 20:35
@changeset-bot
Copy link

changeset-bot bot commented May 15, 2025

🦋 Changeset detected

Latest commit: 2b3b0c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
chainlink-deployments-framework Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@giogam giogam force-pushed the CLD-252/add-a-default-request-timeout-to-multi-client branch from 290e116 to 4390dfa Compare May 15, 2025 20:43
@graham-chainlink graham-chainlink dismissed their stale review May 16, 2025 01:43

some changes

@graham-chainlink
Copy link
Collaborator

So we are exposing context for each public method in this PR, which means user can pass down their own context with timeout, but then inside each method we override it with the RetryConfig timeout value, should we honour their timeout too or not?

I would expect that if a method accepts context , it should uses it like DialContext in postgres.

A thought is that if we really want to enforce our own timeout, maybe we could set out own timeout if there are no existing timeout set in the user pass in context? Not super sure, lets see what everyone else thinks.

func WithTimeoutIfNone(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
    // Check if the parent context already has a deadline
    if _, hasDeadline := parent.Deadline(); hasDeadline {
        // Return the original context and a no-op cancel function
        return parent, func() {}
    }

    // No deadline: apply timeout
    return context.WithTimeout(parent, timeout)
}

// usage

ctx, cancel := WithTimeoutIfNone(ctx, DEFAULT_TIMEOUT)

Also with WaitMined, then now there is some inconsistency, a new user could set timeout on the RetryConfig but then doent know that it doesnt affect WaitMined but it affect the rest, a surprise?

@giogam
Copy link
Contributor Author

giogam commented May 16, 2025

So we are exposing context for each public method in this PR, which means user can pass down their own context with timeout, but then inside each method we override it with the RetryConfig timeout value, should we honour their timeout too or not?

Good question. I looked into the ethclient implementation and contract bindings, and it does appear possible to inject a context from a changeset. The contract bindings accept context via TransactOpts, see here and here.
The ethclient implementation handles this in a similar way to what you suggested, for example, here. I’d say it’s unlikely someone is doing this, but it’s definitely possible. I’m happy to update the code with your suggestion, it’s a small change anyway.

Also with WaitMined, then now there is some inconsistency, a new user could set timeout on the RetryConfig but then doent know that it doesnt affect WaitMined but it affect the rest, a surprise?

For WaitMined, I think it makes sense to have a separate, and potentially longer, timeout, since transactions can sometimes take a while to get mined. We could improve the code to make this configurable, but I’d still keep it as a separate setting from the client retry config.

@graham-chainlink
Copy link
Collaborator

For WaitMined, I think it makes sense to have a separate, and potentially longer, timeout, since transactions can sometimes take a while to get mined. We could improve the code to make this configurable, but I’d still keep it as a separate setting from the client retry config.

Sounds good! lets make sure we comment it so users know as well

@giogam giogam force-pushed the CLD-252/add-a-default-request-timeout-to-multi-client branch from 2c7289e to ae836e6 Compare May 19, 2025 12:51
@giogam giogam requested a review from graham-chainlink May 19, 2025 12:55
@giogam giogam added this pull request to the merge queue May 19, 2025
Merged via the queue into main with commit b3fec25 May 19, 2025
6 checks passed
@giogam giogam deleted the CLD-252/add-a-default-request-timeout-to-multi-client branch May 19, 2025 13:28
github-merge-queue bot pushed a commit that referenced this pull request May 19, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## chainlink-deployments-framework@0.1.3

### Patch Changes

-
[#84](#84)
[`b3fec25`](b3fec25)
Thanks [@giogam](https://github.com/giogam)! - feat(multiclient): adds
timeouts to retryWithBackups and dialWithRetry

---------

Co-authored-by: app-token-issuer-engops[bot] <144731339+app-token-issuer-engops[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants