Skip to main content

SupervisorConfig

Struct SupervisorConfig 

Source
pub struct SupervisorConfig {
    pub initial_backoff: Duration,
    pub max_backoff: Duration,
    pub mandatory_stop: Duration,
    pub max_attempts: Option<u32>,
    pub anti_thrash_threshold: Option<AntiThrashThreshold>,
    pub drop_grace: Duration,
    pub max_backoff_after_thrash: Duration,
}
Expand description

Configuration for the auto-reconnect supervisor.

The supervisor uses an exponential-backoff schedule between reconnect attempts. All durations are wall-clock; jitter is applied deterministically (seeded from Backoff::new).

Fields§

§initial_backoff: Duration

Initial backoff delay applied to the first reconnect attempt after a drop.

§max_backoff: Duration

Maximum backoff delay; subsequent doubled delays clamp here.

§mandatory_stop: Duration

Cumulative-elapsed cap before the schedule snaps to max_backoff. Mirrors Java’s Backoff.mandatoryStop.

§max_attempts: Option<u32>

Maximum total reconnect attempts. None means infinite — keep reconnecting forever (matching Java’s default). Some(N) gives up after N consecutive failures and surfaces the last error to the caller.

§anti_thrash_threshold: Option<AntiThrashThreshold>

Anti-thrash detector threshold (ADR-0028). None (the default) disables the detector and preserves current behaviour — the supervisor uses only per-handle backoff and the in-band transient retry path.

When Some(threshold), the supervisor escalates to a connection-level cooldown once threshold.successful_attaches consecutive re-attaches succeed and each is followed by a TCP-level drop within threshold.drop_within (all inside threshold.window). The cooldown floor is Self::max_backoff_after_thrash.

Recommended starting values when opting in (see ADR-0028 §“Defaults and migration”): AntiThrashThreshold { successful_attaches: 5, window: Duration::from_secs(2), drop_within: Duration::from_millis(50) } with max_backoff_after_thrash = Duration::from_secs(30).

§drop_grace: Duration

Driver-side grace window for attributing a transport close to a recent successful re-attach. When a TransportClosed arrives within drop_grace of the most recent ConnectionEvent::ProducerReady or ConnectionEvent::SubscribeAcked, the engine driver feeds it into the anti-thrash detector as a ReAttachOutcomeKind::TcpDropAfterReAttach. Defaults to Duration::from_millis(500).

The stricter per-pair drop_within knob on AntiThrashThreshold decides whether the paired entry actually counts toward the threshold — drop_grace is the engine-side attribution window only.

§max_backoff_after_thrash: Duration

Cooldown floor applied once Self::anti_thrash_threshold trips. Stacks above the per-handle backoff; the supervisor sleeps until at least now + max_backoff_after_thrash before its next Transport::connect once the cooldown engages. Default Duration::from_secs(30).

Implementations§

Source§

impl SupervisorConfig

Source

pub fn build_backoff(&self, seed: u64) -> Backoff

Build a Backoff from this config. seed controls jitter; pass 0 for the deterministic default seed.

Source

pub fn should_reset_backoff(&self, socket_alive: Duration) -> bool

Policy gate for the engine drivers’ persisted Backoff schedule: returns true when the previous socket survived past Self::drop_grace — i.e. when the previous reconnect counts as stable and the engine should call Backoff::reset at the top of the next reconnect cycle.

Sockets that died inside drop_grace of the most recent successful attach are treated as thrashes: the schedule keeps growing, so successive ProducerReady-then-drop cycles slow down geometrically up to max_backoff. This is the per-handle defence in depth that pairs with the connection-level anti-thrash cooldown (ADR-0028) — both must be wired for the supervisor to bound CPU under the storm pattern hit by clients sitting behind the Apache Pulsar Proxy.

Engines call this from the top of the supervisor outer loop with the wall-clock-elapsed time between the previous socket coming up and driver_loop_inner returning (i.e. the socket’s lifetime).

Source

pub fn should_give_up(&self, attempts: u32) -> bool

Give-up policy gate for the engine drivers’ reconnect budget (ADR-0061).

Returns true once attempts post-drop dial+handshake attempts have been spent without landing a stable session — i.e. when the supervisor must stop reconnecting and surface the last error to the caller. max_attempts == None (the default) never gives up, matching Java’s infinite reconnect.

attempts is the COUNT OF FAILED CYCLES, hoisted so it spans the FULL dial+handshake cycle: a TCP-dial failure AND a post-dial handshake failure each count as one. Behind a TCP-accepting proxy / LB whose backend is down — the storm class the anti-thrash supervision was built for — the dial always succeeds but the Pulsar handshake never completes; counting only dial failures (the pre-ADR-0061 behaviour) let the budget never fire, so the driver retried forever. Counting EVERY post-dial failure uniformly (without distinguishing broker-said-no from connection-dropped) is the simplest rule and matches Java’s bounded reconnect.

The counter is reset to 0 by the engine ONLY when Self::should_reset_backoff is true for the previous socket’s lifetime — so give-up-reset and backoff-reset share ONE stability definition (a connection that survived drop_grace). A socket that merely accepted TCP and handshaked but died inside drop_grace does NOT reset the budget.

Trait Implementations§

Source§

impl Clone for SupervisorConfig

Source§

fn clone(&self) -> SupervisorConfig

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 SupervisorConfig

Source§

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

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

impl Default for SupervisorConfig

Source§

fn default() -> SupervisorConfig

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

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> 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.

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

Source§

type Output = T

Should always be Self
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 = !

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<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