Skip to main content

LoadBalancerGroup

Struct LoadBalancerGroup 

Source
pub struct LoadBalancerGroup<S>{
    pub health_check_frequency: Option<Duration>,
    pub update_frequency: Option<Duration>,
    pub parallel_health_check: bool,
    /* private fields */
}
Expand description

A collection of eventually consistent load-balancing selectors that share one backend pool.

Discovery membership and readiness are published independently from selector construction. Each selector continues serving its previous generation while its replacement is built on a blocking worker. Pending updates are coalesced so that at most one newer generation waits behind an in-progress build or a shared rebuild gate. Selector builds and retired generations are bounded by a SelectorRebuildGate.

Each published selector owns the readiness snapshot for its generation, so a removed backend stays selectable only through selectors still serving an older generation. That readiness is released when the selector is replaced and its last reader drops it; no separate pruning step is needed.

Fields§

§health_check_frequency: Option<Duration>

How frequently the health check logic (if set) should run.

If None, the health check logic will only run once at the beginning. This setting is ignored for views created with BackendView::new_with_health_registry; use HealthCheckService for those views.

§update_frequency: Option<Duration>

How frequently service discovery should run.

If None, service discovery will only run once at the beginning.

§parallel_health_check: bool

Whether to run health checks for all backends in parallel. Default is false.

Implementations§

Source§

impl<S: Send + Sync + BackendSelection + 'static> LoadBalancerGroup<S>
where S::Config: 'static, S::Iter: BackendIter,

Source

pub async fn run( &self, shutdown: ShutdownWatch, ready_opt: Option<ServiceReadyNotifier>, )

Run discovery, selector rebuilds, and privately managed health checks until shutdown.

Source§

impl<S> LoadBalancerGroup<S>
where S: BackendSelection + Send + Sync + 'static, S::Config: 'static, S::Iter: BackendIter,

Source

pub fn from_backends_with_configs( backends: Backends, configs: impl IntoIterator<Item = Option<S::Config>>, ) -> Self

Build a group of selectors over one shared backend pool.

Each item in configs creates one selector. None uses BackendSelection::build, while Some(config) uses BackendSelection::build_with_config.

§Panics

Panics if backends has already been updated. A group owns backend updates and must start with selector generation zero.

Source

pub fn with_rebuild_gate(self, rebuild_gate: Arc<SelectorRebuildGate>) -> Self

Use a rebuild gate shared with other selector groups.

A group uses a private serial gate by default. Supplying the same gate to multiple groups extends the one-extra-generation memory bound across all of them.

Source

pub fn selector_count(&self) -> usize

Return the number of selectors in this group.

Source

pub async fn update(&self) -> Result<()>

Run service discovery and enqueue selector rebuilds when membership changes.

The discovered backend membership is published before this method returns. Selector rebuilds run asynchronously. A removed backend stays selectable through selectors still serving an older generation, via the readiness snapshot each of those selectors owns.

To wait for convergence, read backend_generation after this call and poll selectors_ready_for. Calls on the same group must not overlap. Self::run serializes them.

Source

pub fn select( &self, selector_index: usize, key: &[u8], max_iterations: usize, ) -> Option<Backend>

Return the first healthy backend from the selected load-balancing configuration.

Returns None when selector_index is out of bounds.

Source

pub fn select_with<F>( &self, selector_index: usize, key: &[u8], max_iterations: usize, accept: F, ) -> Option<Backend>
where F: Fn(&Backend, bool) -> bool,

Select a backend using one selector and an additional acceptance function.

Each selector consults the readiness snapshot published with it, so a selector serving an older generation keeps using that generation’s readiness. Returns None when selector_index is out of bounds.

Source

pub fn set_health_check( &mut self, hc: Box<dyn HealthCheck + Send + Sync + 'static>, )

Set the health check implementation shared by every selector.

Source

pub fn backends(&self) -> &Backends

Access the shared backend pool.

Source

pub fn backend_generation(&self) -> u64

Return the latest backend membership generation.

Source

pub fn selector_generation(&self, selector_index: usize) -> Option<u64>

Return the generation currently served by one selector.

Source

pub fn selectors_ready_for(&self, generation: u64) -> bool

Return whether every selector serves at least generation.

Source

pub fn selector_last_update_timing( &self, selector_index: usize, ) -> Option<SelectorUpdateTimings>

Return timing information for the most recently published selector generation.

Source

pub fn selector_coalesced_rebuilds(&self, selector_index: usize) -> Option<u64>

Return how many pending selector generations were replaced by a newer one.

Source

pub fn selector_failed_rebuilds(&self, selector_index: usize) -> Option<u64>

Return how many selector rebuild tasks failed.

Source

pub fn last_update_timing(&self) -> Option<UpdateTimings>

Return timing information from the most recent successful update.

Trait Implementations§

Source§

impl<S: Send + Sync + BackendSelection + 'static> BackgroundService for LoadBalancerGroup<S>
where S::Config: 'static, S::Iter: BackendIter,

Source§

fn start_with_ready_notifier<'life0, 'async_trait>( &'life0 self, shutdown: ShutdownWatch, ready: ServiceReadyNotifier, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

This function is called when the pingora server tries to start all the services. The background service should signal readiness by calling ready_notifier.notify_ready() once initialization is complete. The service can return at anytime or wait for the shutdown signal. Read more
Source§

fn start<'life0, 'async_trait>( &'life0 self, shutdown: ShutdownWatch, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

This function is called when the pingora server tries to start all the services. The background service can return at anytime or wait for the shutdown signal.
Source§

impl<S> Drop for LoadBalancerGroup<S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<S> !Freeze for LoadBalancerGroup<S>

§

impl<S> !RefUnwindSafe for LoadBalancerGroup<S>

§

impl<S> !UnwindSafe for LoadBalancerGroup<S>

§

impl<S> Send for LoadBalancerGroup<S>
where Box<[Arc<SelectorSlot<S>>]>: Send,

§

impl<S> Sync for LoadBalancerGroup<S>
where Box<[Arc<SelectorSlot<S>>]>: Sync,

§

impl<S> Unpin for LoadBalancerGroup<S>
where Box<[Arc<SelectorSlot<S>>]>: Unpin,

§

impl<S> UnsafeUnpin for LoadBalancerGroup<S>
where Box<[Arc<SelectorSlot<S>>]>: UnsafeUnpin,

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

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

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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

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