-
Notifications
You must be signed in to change notification settings - Fork 321
Open
Labels
A-retryArea: The tower "retry" middlewareArea: The tower "retry" middlewareC-enhancementCategory: A PR with an enhancement or a proposed on in an issue.Category: A PR with an enhancement or a proposed on in an issue.E-help-wantedCall for participation: Help is requested to fix this issue.Call for participation: Help is requested to fix this issue.E-mediumCall for participation: Experience needed to fix: Medium / intermediateCall for participation: Experience needed to fix: Medium / intermediateP-highHigh priorityHigh priority
Description
This issue scopes out the changes we are proposing to the retry middleware to improve its ergonomics. Currently, the retry middleware is quite hard to use and requires implementing a custom Policy. Writing this policy is non-trivial and is more work than it should be.
These improvements are aimed at setting up retries with tower to be easier and more user friendly. As well as providing good defaults that work out of the box.
List of improvements to tower and tower-http:
- Simplify
Policy(retry: ChangePolicyto accept&mut self#681).- Change trait fn to take
&mut self. - Change
Futureoutput to(). - Alllow
Policyto be object safe.
- Change trait fn to take
- Add generic backoff utilities. retry: Add generic backoff utilities #685
- Add some
trait Backoffthat has an associated future type that allows others to use this utility without being tied totokio::time. - Add a
ExponentialBackofftype that implementsBackoff, ported fromlinkerd2-proxy. - Add
Rngutilities util: Addrngutilities #686
- Add some
- Budget improvements.
- Merge budget docs PR (docs: improve docs of
retry budget#613). - Implement simpler non-time based token bucket budget.
- Add some
Budgettrait to allow users to choose which implementation to use.
- Merge budget docs PR (docs: improve docs of
- Add a new batteries included standard retry policy retry: Add
StandardRetryPolicyandstandard_policymod #698- New
StandardRetryPolicycombiningimpl Backoffandimpl Budget. - Add
StandardRetryPolicyBuilderthat accept closures (?) foris_retryable(&mut Req, &mut Result<Res, E>) -> booland aclone_request(&Req) -> Option<Req>.
- New
-
tower-httpimprovements.- Add new
retrymodule - Implement
ReplayBodysimilar to the one implemented inlinkerd2-proxy. - Add new
HttpRetrylayer that accepts higher level constructs for retrying, likeClassifyResponse, and will wrap http request bodies withReplayBody.
- Add new
- Documentation
- Blog post on how to setup retries with
towerandtower-http. - Examples for thick clients with retries in both
towerandtower-http.
- Blog post on how to setup retries with
Example code
tower examples with no http:
let policy = StandardRetryPolicy::builder()
.should_retry(|res| match res {
Ok(_) => false,
Err(_) => true,
})
.clone_request(|r| Some(*r))
.build();
let mut svc = ServiceBuilder::new()
.retry(policy)
.buffer(10)
.timeout(Duration::from_secs(10))
.service(svc);tower-http examples:
let make_classifier = ServerErrorsAsFailures::make_classifier();
let mut svc = ServiceBuilder::new()
.set_request_id("Request-Id".try_into().unwrap(), MakeRequestUuid)
.retry(StandardHttpPolicy::new(
make_classifier,
ExponentialBackoff::default(),
Budget::default(),
|e| match e {
ServerErrorsFailureClass::Status(s) => true,
ServerErrorsFailureClass::Error(s) => false,
},
))
.timeout(Duration::from_secs(5))
.service(client);tobz, Folyd, lovesegfault, seanmonstar, m-rots and 8 more
Metadata
Metadata
Assignees
Labels
A-retryArea: The tower "retry" middlewareArea: The tower "retry" middlewareC-enhancementCategory: A PR with an enhancement or a proposed on in an issue.Category: A PR with an enhancement or a proposed on in an issue.E-help-wantedCall for participation: Help is requested to fix this issue.Call for participation: Help is requested to fix this issue.E-mediumCall for participation: Experience needed to fix: Medium / intermediateCall for participation: Experience needed to fix: Medium / intermediateP-highHigh priorityHigh priority