RetryConfig

Struct RetryConfig 

Source
pub struct RetryConfig {
    pub attempts: u32,
    pub retry_post: bool,
    pub backoff_base_ms: u64,
    pub backoff_cap_ms: u64,
    pub retry_statuses: Vec<u16>,
    pub retry_transport: bool,
    pub budget_percent: u32,
    pub buffer_max_bytes: u64,
    pub hedge: Option<HedgeConfig>,
    pub total_deadline_ms: Option<u64>,
    pub buffer_first_frame_bytes: u64,
}
Expand description

Upstream retry knobs (DW-014). All fields default; a retries: block with no keys is equivalent to retries off (attempts defaults to 0).

Frozen semantics (see upstream/proxy/retries module docs):

  • attempts is the maximum number of RETRIES beyond the first attempt (0 = off). Validation caps it at 10.
  • Only requests whose body was fully buffered within buffer_max_bytes may be retried; an over-cap body streams without retry. Buffering is opt-in: the default (0) buffers only empty bodies, so the default proxy path stays unbuffered.
  • Retries happen strictly BEFORE response headers arrive on the final attempt; a response body that dies mid-stream is never retried (its failure is reported to passive health instead).
  • Every retried attempt is charged against the upstream’s rolling-window retry budget (budget_percent).
  • total_deadline_ms (REL-01) caps the wall-clock time from the first attempt to the last, INCLUDING backoff delays between attempts. Absent leaves the cross-attempt budget unbounded (the v1 default, kept for backwards compatibility). When set, a retry whose backoff would cross the deadline is aborted and the last response/error is returned to the client; the per-attempt read_ms timeout still bounds each individual attempt. Standard in Envoy and NGINX.

Fields§

§attempts: u32

Maximum retries beyond the first attempt (default 0 = off).

§retry_post: bool

Retry non-idempotent POST requests. Default false: POST is never retried unless an operator explicitly opts in here (a retried POST may replay a body the upstream already partially processed).

§backoff_base_ms: u64

Exponential backoff base in milliseconds (default 25): the nominal delay before retry n is min(base * 2^(n-1), backoff_cap_ms).

§backoff_cap_ms: u64

Exponential backoff ceiling in milliseconds (default 250). Must be

= backoff_base_ms.

§retry_statuses: Vec<u16>

Response statuses that trigger a retry when received as the upstream response status (default [502, 503, 504]). Each entry must be a valid 4xx/5xx status. An empty list disables status-based retries.

§retry_transport: bool

Retry on transport errors (connect timeout/refusal/reset/framing) and per-attempt read timeouts (default true).

§budget_percent: u32

Retry budget: the maximum percentage of requests to this upstream, in a rolling window, that may be retries (default 10). Must be in (0, 100]. When the budget is exhausted, failing requests fail through to the client instead of retrying.

§buffer_max_bytes: u64

Request-body buffering cap in bytes (default 0 = no buffering). A request body is buffered (and becomes replayable) only while it fits within this cap; larger bodies stream and are never retried.

§hedge: Option<HedgeConfig>

Request hedging (DW-063): after hedge_after_ms milliseconds without a response, a speculative duplicate request is sent to a different endpoint; the first response wins and the loser is cancelled. Requires buffer_max_bytes > 0 (the body must be replayable to send a hedge copy) and idempotent methods (GET, HEAD, OPTIONS, TRACE, PUT) — POST is hedged only when retry_post is also true. Absent (or hedge_after_ms = 0) disables hedging. At most hedge_max speculative copies are sent per request (default 1).

§total_deadline_ms: Option<u64>

Cross-attempt total retry deadline in milliseconds (REL-01): caps the wall-clock time from the first attempt to the last, INCLUDING backoff delays between attempts. Absent leaves the cross-attempt budget unbounded (the v1 default, kept for backwards compatibility). When set, a retry whose backoff would cross the deadline is aborted and the last response/error is returned to the client; the per-attempt read_ms timeout still bounds each individual attempt. Must be in (0, MAX_RETRY_TOTAL_DEADLINE_MS]; 0 is rejected (omit the field for unbounded).

§buffer_first_frame_bytes: u64

Streaming failover first-frame buffer cap in bytes (REL-05, #216). When > 0, the proxy buffers up to this many bytes of the upstream response body BEFORE forwarding any bytes to the client. If the upstream fails (connection reset, read timeout, framing error) before the buffer fills or the body completes, the proxy can still retry the request to a different endpoint — the client has not yet received any bytes, so the response is not committed. Once the buffer fills (or the body completes), the buffered prefix is flushed to the client and the rest of the body streams frame-by-frame (the stream is then committed; a later mid-body failure is terminal, as in v1). Default 0 = no first-frame buffering (v1 behavior: the response is committed as soon as headers resolve). Requires attempts > 0 and buffer_max_bytes > 0 (the request body must be replayable).

Trait Implementations§

Source§

impl Clone for RetryConfig

Source§

fn clone(&self) -> RetryConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for RetryConfig

Source§

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

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

impl Default for RetryConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for RetryConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl JsonSchema for RetryConfig

Source§

fn schema_name() -> Cow<'static, str>

The name of the generated JSON Schema. Read more
Source§

fn schema_id() -> Cow<'static, str>

Returns a string that uniquely identifies the schema produced by this type. Read more
Source§

fn json_schema(generator: &mut SchemaGenerator) -> Schema

Generates a JSON Schema for this type. Read more
Source§

fn inline_schema() -> bool

Whether JSON Schemas generated for this type should be included directly in parent schemas, rather than being re-used where possible using the $ref keyword. Read more
Source§

impl PartialEq for RetryConfig

Source§

fn eq(&self, other: &RetryConfig) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for RetryConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for RetryConfig

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
§

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

§

fn downcast_ref<T>(this: &Self) -> Option<&T>
where T: Any,

Attempts to downcast this to T behind reference
§

fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>
where T: Any,

Attempts to downcast this to T behind mutable reference
§

fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>
where T: Any,

Attempts to downcast this to T behind Rc pointer
§

fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>
where T: Any,

Attempts to downcast this to T behind Arc pointer
§

fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>
where T: Any,

Attempts to downcast this to T behind Box pointer
§

fn downcast_move<T>(this: Self) -> Option<T>
where T: Any, Self: Sized,

Attempts to downcast owned Self to T, useful only in generic context as a workaround for specialization
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
§

impl<T, X> CoerceTo<T> for X
where T: CoerceFrom<X> + ?Sized,

§

fn coerce_rc_to(self: Rc<X>) -> Rc<T>

§

fn coerce_box_to(self: Box<X>) -> Box<T>

§

fn coerce_ref_to(&self) -> &T

§

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

Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> ServiceExt for T

§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
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.
§

impl<T> TryIntoValue for T
where T: Serialize,

§

type Error = SerializationError

§

fn try_into_value(self) -> Result<Value, <T as TryIntoValue>::Error>

§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,