pub struct RetryPolicy {
pub max_attempts: usize,
pub per_attempt_deadline: Duration,
pub overall_deadline: Duration,
pub base_backoff: Duration,
pub leader_ttl: Duration,
}Expand description
Retry and deadline knobs for client RPCs.
Every field has a default chosen for steady-state availability; see
RetryPolicy::default for the values. Pass a customised policy via
crate::ClientBuilder::retry_policy when the defaults don’t match
your deployment (for example, longer per_attempt_deadline for
cross-region servers, or tighter overall_deadline for
latency-sensitive paths).
Fields§
§max_attempts: usizeMaximum number of failed attempts issue_rpc will make before
returning the last error — that is, endpoints dialed that returned
an error, not total loop iterations.
The budget is floored at the size of the initial worklist (the cached
leader, if fresh, plus the configured endpoints), so a single
cold-cache sweep always dials every endpoint at least once even when
max_attempts is smaller than the endpoint count. Without this floor,
the randomly seeded rotation offset in ChannelPool::iter_round_robin
could leave the only reachable endpoint untried whenever a pool has
more configured endpoints than max_attempts. The overall_deadline
still bounds the worst case, so a pool full of dead peers cannot dial
forever.
Leader-hint redirects are not charged against this budget (they are
known discovery progress, bounded instead by the per-endpoint
visited-set, the overall_deadline, the per-pass MAX_LEADER_REDIRECTS
cap, and the absolute, cross-pass MAX_TOTAL_LEADER_REDIRECTS backstop in
crate::retry), so a legitimate failover redirect chain can be longer
than max_attempts and still reach the live leader (issue #340).
per_attempt_deadline: DurationWall-clock deadline applied to each (connect, get_ts) pair.
Pushed down to Endpoint::connect_timeout / Endpoint::timeout
for the built-in transport paths, and enforced by an outer
tokio::time::timeout for user-supplied
crate::ClientBuilder::channel_connector closures.
overall_deadline: DurationWall-clock deadline for the entire issue_rpc call. Once
elapsed, the retry loop returns the last observed error rather
than starting another attempt — even if max_attempts and the
worklist still have headroom.
base_backoff: DurationBase unit for the jittered exponential backoff applied between
attempts whose last error was Unavailable or DeadlineExceeded.
The actual sleep is rand_uniform(0, base_backoff * 2^attempt),
capped internally at RetryPolicy::MAX_BACKOFF so a long
base_backoff plus a high attempt count cannot consume the
overall deadline in a single sleep.
leader_ttl: DurationFreshness bound on the cached leader endpoint. The cache is touched on every successful RPC against the cached leader, so a busy steady-state leader is retained indefinitely. The TTL only bites when the leader falls quiet — past it, the next RPC re-evaluates the configured endpoint list rather than pinning to a possibly-dead endpoint that has not been re-validated within the window.
Implementations§
Source§impl RetryPolicy
impl RetryPolicy
Sourcepub const MAX_BACKOFF: Duration
pub const MAX_BACKOFF: Duration
Upper bound on a single backoff sleep, regardless of
base_backoff and attempt count. Prevents the jittered
exponential from sleeping past the overall deadline in one step.
Trait Implementations§
Source§impl Clone for RetryPolicy
impl Clone for RetryPolicy
Source§fn clone(&self) -> RetryPolicy
fn clone(&self) -> RetryPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RetryPolicy
impl Debug for RetryPolicy
Source§impl Default for RetryPolicy
impl Default for RetryPolicy
Source§fn default() -> Self
fn default() -> Self
max_attempts = 5, per_attempt_deadline = 2s,
overall_deadline = 10s, base_backoff = 50ms,
leader_ttl = 30s. Five attempts at the per-attempt cap plus
modest backoff fit inside the overall deadline for the common
case; the loop returns NoReachableEndpoints (or the last
status) once exhausted. The 30-second TTL is roughly 3× the
overall deadline — long enough that a steady-state leader is
retained across normal request gaps, short enough that a leader
that fell silent at startup is re-evaluated before too many
callers fail-fast on the cached pin.
Auto Trait Implementations§
impl Freeze for RetryPolicy
impl RefUnwindSafe for RetryPolicy
impl Send for RetryPolicy
impl Sync for RetryPolicy
impl Unpin for RetryPolicy
impl UnsafeUnpin for RetryPolicy
impl UnwindSafe for RetryPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request