Skip to main content

RetryPolicy

Struct RetryPolicy 

Source
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: usize

Maximum 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: Duration

Wall-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: Duration

Wall-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: Duration

Base 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: Duration

Freshness 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

Source

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

Source§

fn clone(&self) -> RetryPolicy

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RetryPolicy

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for RetryPolicy

Source§

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more