-
Notifications
You must be signed in to change notification settings - Fork 20
feat: add retry strategy to client #512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
evm_rpc_client/src/lib.rs
Outdated
| where | ||
| Config: CandidType + Send, | ||
| Params: CandidType + Send, | ||
| Config: CandidType + Clone + Send, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Clone bounds are needed here to be able to clone the request when retrying.
evm_rpc_client/src/retry/mod.rs
Outdated
|
|
||
| /// The retry strategy when performing calls to the EVM RPC canister. | ||
| #[derive(Clone, Eq, PartialEq, Debug, Default)] | ||
| pub enum EvmRpcRetryStrategy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hesitated here to make this a trait instead of an enum, so users can provide their own retry implementation. In the end, I felt like it might have been over-engineered though and an enum might be sufficient. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One problem I see is that if we need some additional trait bounds for a new variant in EvmRpcRetryStrategy, then this will trickle down to all methods, such as try_execute_request, even if the caller would not use this particular variant. For that reason, my impression is that having a trait here would be useful. Something like in the spirit of tower::retry::Policy. One benefit is that the trait EvmRpcResult would also I think no longer be necessary, because the bound would be on the strategy implementing RetryPolicy. Example
pub trait RetryPolicy<Config, Params, CandidOutput, Output> {
fn retry(
&mut self, //can mutate self in case the strategy is stateful
request: Request<Config, Params, CandidOutput, Output>, //take ownership, no separate_method `clone_request
result: &mut Result<Output, IcError>, //strategy can decide to change result
) -> Option<Request<Config, Params, CandidOutput, Output>>;
}WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually originally had something very similar, and then moved to an enum... But I think you make some good points and in the end the more complicated solution is indeed probably better.
Note that I did add a clone_request method, otherwise, even with a NoRetry policy, requests would still need to be cloneable. This means we effectively have something extremely similar to tower::retry::Policy, and so I'm wondering if in the end it might not make more sense to just use that? We could use tower for the whole thing which would just require adding a 'static bound on the Config and Params types. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes, the trait looks very good to me!
and so I'm wondering if in the end it might not make more sense to just use that?
For now I would not, for the following reasons:
- less dependencies
- simpler, because the current retry policy does not need to be async.
gregorydemay
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the refactoring @lpahlavi ! Some minor comments but otherwise looks very good to me!
evm_rpc_client/src/retry/mod.rs
Outdated
|
|
||
| /// The retry strategy when performing calls to the EVM RPC canister. | ||
| #[derive(Clone, Eq, PartialEq, Debug, Default)] | ||
| pub enum EvmRpcRetryStrategy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes, the trait looks very good to me!
and so I'm wondering if in the end it might not make more sense to just use that?
For now I would not, for the following reasons:
- less dependencies
- simpler, because the current retry policy does not need to be async.
|
Thanks a lot for the review and input @gregorydemay! This should be ready for another round. |
## 🤖 New release * `evm_rpc_client`: 0.1.0 -> 0.2.0 (✓ API compatible changes) * `evm_rpc`: 2.6.0 -> 2.7.0 (✓ API compatible changes) <details><summary><i><b>Changelog</b></i></summary><p> ## `evm_rpc_client` <blockquote> ## [0.2.0] - 2025-11-03 ### Added - Add `.request_cost()` method to `RequestBuilder` to compute the cycles cost of a request via the new `CyclesCost` query endpoints ([#509](#509)) - Add the option to configure a retry strategy in the EVM RPC client to e.g., try a request with increasingly many cycles if it fails to to insufficient cycles ([#512](#512)) [0.2.0]: evm_rpc_client-v0.1.0...evm_rpc_client-v0.2.0 </blockquote> ## `evm_rpc` <blockquote> ## [2.7.0] - 2025-11-03 ### Added - For each `eth_*` endpoint, add a new corresponding `eth_*CyclesCost` query endpoint with the same Candid arguments, that allows computing the cycles cost of calling the corresponding `eth_*` update endpoint ([#508](#508), [#509](#509)) ### Changed - Use constant-size request IDs in JSON-RPC requests to allow for consistent request cycles costs ([#514](#514)) [2.7.0]: v2.6.0...v2.7.0 </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Louis Pahlavi <[email protected]>
Add the option of configuring a retry strategy to the
EvmRpcClientin order to double the amount of cycles attached to a call until it succeeds.