pub struct UpstreamLb { /* private fields */ }Expand description
A load balancer for one upstream: lock-free picks over an atomically
swappable endpoint set. Share via Arc; cheap to read from any task.
Implementations§
Source§impl UpstreamLb
impl UpstreamLb
Sourcepub fn new(
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
) -> Arc<Self>
pub fn new( endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, ) -> Arc<Self>
Build a balancer with a fresh endpoint set (all slow-start clocks
start now) and passive health DISABLED. See UpstreamLb::new_with_health.
Sourcepub fn new_with_health(
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
health: Option<&PassiveHealth>,
) -> Arc<Self>
pub fn new_with_health( endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, health: Option<&PassiveHealth>, ) -> Arc<Self>
new with passive health (DW-012): when health is Some, every
endpoint gets a fresh health tracker and picks skip ejected
endpoints (all-ejected falls back to the full set; see choose).
The config form is resolved via HealthParams::from_config;
validation guarantees its bounds.
Sourcepub fn new_with_health_and_events(
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
health: Option<&PassiveHealth>,
events: Option<&UpstreamEmitter>,
peak_ewma: Option<&PeakEwmaConfig>,
locality: Option<&UpstreamLocality>,
) -> Arc<Self>
pub fn new_with_health_and_events( endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, health: Option<&PassiveHealth>, events: Option<&UpstreamEmitter>, peak_ewma: Option<&PeakEwmaConfig>, locality: Option<&UpstreamLocality>, ) -> Arc<Self>
new_with_health with ejection/recovery events (DW-044): fresh
trackers are created bound to events (an upstream-labeled
emitter), so their ejection/recovery transitions emit onto the
event bus. Carried trackers keep the binding they were built
with. None behaves exactly like UpstreamLb::new_with_health.
peak_ewma (DW-090) is the per-upstream tuning consulted only
when algorithm == PeakEwma; None uses the built-in defaults.
locality (DW-094, Ent) is the per-upstream locality-aware
routing config; None disables locality filtering.
Sourcepub fn rebuild(
&self,
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
)
pub fn rebuild( &self, endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, )
Hot-swap the endpoint set and/or algorithm (passive health
disabled; see UpstreamLb::rebuild_with_health). Unchanged
addresses keep their in-flight counters, WRR phase, slow-start
entry instant, and health trackers; new addresses start fresh.
Atomic; concurrent picks see either the old or the new set, never
a mix.
Sourcepub fn rebuild_with_health(
&self,
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
health: Option<&PassiveHealth>,
)
pub fn rebuild_with_health( &self, endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, health: Option<&PassiveHealth>, )
rebuild with passive health parameters for the new generation
(DW-012). Unchanged addresses keep their LIVE trackers (streak and
observation window survive the reload); the new parameters apply
to NEW observations only. Health state is carried per
address:port, exactly like in-flight counters; removed endpoints
drop their trackers outright and re-added ones start healthy with
no history.
Sourcepub fn rebuild_with_health_and_events(
&self,
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
health: Option<&PassiveHealth>,
events: Option<&UpstreamEmitter>,
peak_ewma: Option<&PeakEwmaConfig>,
locality: Option<&UpstreamLocality>,
)
pub fn rebuild_with_health_and_events( &self, endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, health: Option<&PassiveHealth>, events: Option<&UpstreamEmitter>, peak_ewma: Option<&PeakEwmaConfig>, locality: Option<&UpstreamLocality>, )
rebuild_with_health with ejection/recovery events (DW-044):
trackers created by THIS rebuild bind events; carried trackers
keep their original binding (the emitter is per-dataplane and
stable, so in practice the two agree). None behaves exactly
like UpstreamLb::rebuild_with_health. peak_ewma (DW-090) is
the per-upstream tuning consulted only when
algorithm == PeakEwma; None uses the built-in defaults.
locality (DW-094, Ent) is the per-upstream locality-aware
routing config; None disables locality filtering for this
generation.
Sourcepub fn rebuild_with_resolved_health_and_events(
&self,
endpoints: &[Endpoint],
algorithm: LoadBalancer,
slow_start: Duration,
health: Option<Arc<HealthParams>>,
events: Option<&UpstreamEmitter>,
peak_ewma: Option<&PeakEwmaConfig>,
locality: Option<&UpstreamLocality>,
)
pub fn rebuild_with_resolved_health_and_events( &self, endpoints: &[Endpoint], algorithm: LoadBalancer, slow_start: Duration, health: Option<Arc<HealthParams>>, events: Option<&UpstreamEmitter>, peak_ewma: Option<&PeakEwmaConfig>, locality: Option<&UpstreamLocality>, )
DW-042: rebuild_with_health_and_events taking RESOLVED health
parameters (Arc<HealthParams>) instead of the config form. The
DNS discovery task reads the resolved parameters from the current
LbState (via UpstreamLb::health_config) so a live endpoint-set
swap uses the same health parameters as the initial build without
re-resolving the config form. peak_ewma (DW-090) is the
per-upstream tuning consulted only when
algorithm == PeakEwma; None uses the built-in defaults.
locality (DW-094, Ent) is the per-upstream locality-aware
routing config; None disables locality filtering for this
generation.
Sourcepub fn set_health_clock(&self, clock: fn() -> u64)
pub fn set_health_clock(&self, clock: fn() -> u64)
Replace the passive-health clock (Unix-epoch milliseconds; must be cheap). Intended for tests and other time-controlled setups — the same injection pattern as the rate limiter’s clock (DW-004). Production code keeps the default system clock.
Sourcepub fn fail_open_picks(&self) -> u64
pub fn fail_open_picks(&self) -> u64
Picks that served from the full endpoint set because every
endpoint was ejected (fail-open). See choose.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether the current set is empty (only via unvalidated configs).
Sourcepub fn algorithm(&self) -> LoadBalancer
pub fn algorithm(&self) -> LoadBalancer
DW-042: the load-balancing algorithm of the current state. The discovery task reads this so a live endpoint-set swap uses the same algorithm as the initial build.
Sourcepub fn slow_start(&self) -> Duration
pub fn slow_start(&self) -> Duration
DW-042: the slow-start window of the current state. The discovery task reads this so a live endpoint-set swap applies the same slow-start ramp as the initial build.
Sourcepub fn health_config(&self) -> Option<Arc<HealthParams>>
pub fn health_config(&self) -> Option<Arc<HealthParams>>
DW-042: the resolved passive-health parameters of the current state, if passive health is enabled. The discovery task reads this so a live endpoint-set swap creates health trackers with the same parameters as the initial build.
Sourcepub fn peak_ewma_config(&self) -> Option<Arc<PeakEwmaConfig>>
pub fn peak_ewma_config(&self) -> Option<Arc<PeakEwmaConfig>>
DW-090: the resolved peak-EWMA config of the current state, if
the algorithm is peak_ewma. The discovery task reads this so a
live endpoint-set swap uses the same tuning (decay tau, initial
cost) as the initial build.
Sourcepub fn events(&self) -> Option<UpstreamEmitter>
pub fn events(&self) -> Option<UpstreamEmitter>
DW-042: the upstream-scoped event emitter, if the balancer was
built with one. The discovery task passes this to
rebuild_with_health_and_events so new endpoints get
event-bound health trackers.
Sourcepub fn set_locality_context(&self, ctx: LocalityContext)
pub fn set_locality_context(&self, ctx: LocalityContext)
DW-094 (Ent): set the edge’s locality context (region/zone).
Applied to every upstream’s balancer by the dataplane at startup
(from env vars or edge labels). Read on every pick when the
upstream has locality configured; ignored otherwise.
Sourcepub fn locality_config(&self) -> Option<Arc<UpstreamLocality>>
pub fn locality_config(&self) -> Option<Arc<UpstreamLocality>>
DW-094 (Ent): the resolved locality-aware routing config for the current generation, if any. The discovery task reads this so a live endpoint-set swap preserves the locality config.
Sourcepub fn endpoint(&self, idx: usize) -> Option<(String, u16)>
pub fn endpoint(&self, idx: usize) -> Option<(String, u16)>
address:port of endpoint idx in the current set.
Sourcepub fn health_targets(&self) -> Vec<(String, u16, Option<Arc<EndpointHealth>>)>
pub fn health_targets(&self) -> Vec<(String, u16, Option<Arc<EndpointHealth>>)>
Every endpoint’s address:port and passive-health tracker in the
current set, in state order. Trackers are present only when the
generation carries passive health (DW-012). This is the ACTIVE
health engine’s (DW-013) view: probe loops target a SPECIFIC
endpoint and report into its live tracker, bypassing balancing.
Single atomic state load, so address and tracker always correspond.
Sourcepub fn acquire_inflight(self: &Arc<Self>, idx: usize) -> Option<InflightGuard>
pub fn acquire_inflight(self: &Arc<Self>, idx: usize) -> Option<InflightGuard>
Increment endpoint idx’s in-flight counter; returns a guard that
decrements it on drop. Used by the upstream handle around dispatch.
Sourcepub fn record_latency(&self, idx: usize, duration: Duration)
pub fn record_latency(&self, idx: usize, duration: Duration)
Record an observed latency for endpoint idx (DW-090). Updates
the endpoint’s peak-EWMA cost tracker using the Finagle formula:
w = exp(-td / tau)wheretdis the time since the last update andtauis the decay window (peak_ewma.decay_ms).- If
rtt > cost(the new RTT exceeds the current cost), the cost is replaced outright (the “peak” — a slow response is remembered in full so the balancer degrades an outlier immediately). - Otherwise
cost = cost * w + rtt * (1 - w)(the cost decays toward the new RTT).
No-op when the endpoint has no peak-EWMA tracker (the algorithm
is not peak_ewma, or the index is out of range). Lock-free:
the tracker’s cost_ns and stamp are atomics. The latency is
recorded for ALL outcomes (success, error, timeout) since even a
timeout is a latency signal.
Sourcepub fn peak_ewma_cost(&self, idx: usize) -> Option<u64>
pub fn peak_ewma_cost(&self, idx: usize) -> Option<u64>
The current peak-EWMA cost (nanoseconds) for endpoint idx, or
None when the endpoint has no tracker (the algorithm is not
peak_ewma or the index is out of range). Test/diagnostic helper.
Sourcepub fn pick(&self, key: Option<&str>) -> Option<usize>
pub fn pick(&self, key: Option<&str>) -> Option<usize>
Pick the endpoint index for one dispatch. key is the hash key
(client IP) used by ip_hash; other algorithms ignore it. Lock-free.
Sourcepub fn pick_endpoint(&self, key: Option<&str>) -> Option<(usize, String, u16)>
pub fn pick_endpoint(&self, key: Option<&str>) -> Option<(usize, String, u16)>
Single-load pick returning the index AND the endpoint’s
address:port from the SAME state snapshot (no reload can interleave
between pick and resolution). For dispatch paths that do not need
an in-flight guard (e.g. TLS passthrough).
Sourcepub fn pick_for_dispatch(
self: &Arc<Self>,
key: Option<&str>,
) -> Option<Dispatch>
pub fn pick_for_dispatch( self: &Arc<Self>, key: Option<&str>, ) -> Option<Dispatch>
Single-load pick + in-flight acquisition: the algorithm choice, the
endpoint resolution, and the counter increment all happen against
ONE ArcSwap snapshot, so a concurrent rebuild cannot detach the
guard from the endpoint it counted (the guard pins that snapshot).
Prefer this over separate pick/endpoint/acquire_inflight
calls on any dispatch path.
Auto Trait Implementations§
impl !Freeze for UpstreamLb
impl RefUnwindSafe for UpstreamLb
impl Send for UpstreamLb
impl Sync for UpstreamLb
impl Unpin for UpstreamLb
impl UnwindSafe for UpstreamLb
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
§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