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):
attemptsis 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_bytesmay 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-attemptread_mstimeout still bounds each individual attempt. Standard in Envoy and NGINX.
Fields§
§attempts: u32Maximum retries beyond the first attempt (default 0 = off).
retry_post: boolRetry 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: u64Exponential backoff base in milliseconds (default 25): the nominal
delay before retry n is min(base * 2^(n-1), backoff_cap_ms).
backoff_cap_ms: u64Exponential 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: boolRetry on transport errors (connect timeout/refusal/reset/framing) and per-attempt read timeouts (default true).
budget_percent: u32Retry 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: u64Request-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: u64Streaming 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
impl Clone for RetryConfig
Source§fn clone(&self) -> RetryConfig
fn clone(&self) -> RetryConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RetryConfig
impl Debug for RetryConfig
Source§impl Default for RetryConfig
impl Default for RetryConfig
Source§impl<'de> Deserialize<'de> for RetryConfig
impl<'de> Deserialize<'de> for RetryConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for RetryConfig
impl JsonSchema for RetryConfig
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreSource§impl PartialEq for RetryConfig
impl PartialEq for RetryConfig
Source§impl Serialize for RetryConfig
impl Serialize for RetryConfig
impl StructuralPartialEq for RetryConfig
Auto Trait Implementations§
impl Freeze for RetryConfig
impl RefUnwindSafe for RetryConfig
impl Send for RetryConfig
impl Sync for RetryConfig
impl Unpin for RetryConfig
impl UnwindSafe for RetryConfig
Blanket Implementations§
§impl<T> AnyExt for T
impl<T> AnyExt for T
§fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
T behind reference§fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
T behind mutable reference§fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
T behind Rc pointer§fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
T behind Arc pointer§fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
T behind Box pointer§fn downcast_move<T>(this: Self) -> Option<T>
fn downcast_move<T>(this: Self) -> Option<T>
Self to T,
useful only in generic context as a workaround for specializationSource§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,
§impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
impl<T, X> CoerceTo<T> for Xwhere
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
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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