Repository navigation
Count retries, recoveries and exhausted retries per client - #2930
Merged
MarcusSorealheis merged 2 commits intoOct 14, 2026
Merged
Conversation
A store or gRPC client that retries does it silently. When the retries
run out the operation fails with the last error and nothing is logged, so
an incident caused by a throttled backend (an Azure storage account at its
egress limit, say) shows up only as failed actions, and how long the
retries held out has to be reconstructed from sampled logs.
Retrier now records retry.outcomes{retry.client, retry.outcome}:
- retried: an attempt failed with a retryable error and another follows
- recovered: the operation succeeded after at least one retry
- exhausted: the retries ran out on a retryable error
- permanent: an error that is never retried; NotFound is left out, since
on a store it is the ordinary miss
Each retrier is labeled with what it retries for: azure, s3, s3_http,
gcs, ontap_s3, grpc_store, grpc_scheduler and connection. Running out of
retries now also logs a warning naming the client and the attempt.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
MarcusSorealheis
previously approved these changes
Oct 13, 2026
Resolve conflicts with Retry-After support (TraceMachina#2931): the retrier keeps both its client label and outcome hook and the throttle budget, and Azure sets both. A throttle waited out within the budget reports `retried`, and a success after one reports `recovered`, though it spends no attempt. Regenerate the metrics reference.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Cloud stores and gRPC clients retry through
Retrier, and they do it silently. When retries run out the operation fails with the last error and nothing is logged. So an incident caused by a throttled backend, such as a cloud storage account at its egress limit, shows up only as failed actions, and whether retries were attempted, and how long they held out, has to be reconstructed from sampled logs.Retriernow recordsretry.outcomes{retry.client, retry.outcome}:retried: an attempt failed with a retryable error and another attempt followsrecovered: the operation succeeded after at least one retryexhausted: the retries ran out on a retryable errorpermanent: an error that is never retried.NotFoundis left out, since on a store it is the ordinary cache miss.Each retrier names what it retries for, through a new
Retrier::with_client:azure,s3,s3_http,gcs,ontap_s3,grpc_store,grpc_schedulerandconnection. Running out of retries now also logs a warning naming the client and the attempt count.How was this verified?
Not yet compiled or run locally: the Nix dev shell could not download the toolchain on a flaky network, so CI will be the first build. The code is formatted with the repository's nightly rustfmt (2026-08-26).
Tests added in
retry_test.rs, using a newRetrier::with_outcome_fnhook, since the tests cannot read the OTel meter:Retried,Retried,Recovered; success on the first attempt reports nothingmax_retriesreport each retry, thenExhaustedPermanent;NotFoundreports nothingThe existing retry tests are unchanged and should pass as they are:
Retrier::newkeeps its signature, and the client label defaults tounknown.The metrics reference is regenerated (
gen:metrics-reference). Its header moves from v1.7.2 to v1.7.6, so the diff also picks up instruments added since v1.7.2 that the page had not listed.Risk
Low. One counter increment per retry event, on paths that are already failing and sleeping. Label cardinality is eight clients times four outcomes.
The only behavior change is the new
Retries exhaustedwarning: a backend that keeps failing produces one warning per operation that runs out of retries, where before it produced none.AI assistance
I iterated on a prompt, prompted an agent, and did several iterations of review on resulting code.