Skip to main content

BackendMap

Struct BackendMap 

Source
pub struct BackendMap {
    pub backends: HashMap<ClusterId, BackendList>,
    pub health_check_configs: HashMap<ClusterId, HealthCheckConfig>,
    pub protected_health_check_headers: HashMap<ClusterId, ProtectedHeaderSet>,
    pub cluster_http2: HashMap<ClusterId, bool>,
    /* private fields */
}

Fields§

§backends: HashMap<ClusterId, BackendList>§health_check_configs: HashMap<ClusterId, HealthCheckConfig>§protected_health_check_headers: HashMap<ClusterId, ProtectedHeaderSet>

The values behind the headers of a health check, in memory only. An entry is replaced together with its configuration and dropped with it: a configuration that names headers without a set satisfying them sends no probe.

§cluster_http2: HashMap<ClusterId, bool>

Whether the cluster’s backends speak HTTP/2 (cluster.http2 = true). Mirrors the same backend-capability hint the mux router reads at protocol/mux/router.rs::Router::plan_connect. The health checker uses it to switch the probe wire format from HTTP/1.1 to h2c so an h2c-only backend is not probed with an HTTP/1.1 preface that would always fail.

Implementations§

Source§

impl BackendMap

Source

pub fn new() -> BackendMap

A backend map whose randomness is seeded from the OS.

Source

pub fn with_seed(seed: u64) -> BackendMap

A backend map whose every policy seed and backoff jitter derives from seed, for a deterministic simulator (#1684).

Source

pub fn rng(&mut self) -> &mut StdRng

The map’s generator, for a caller that arms a backend’s retry policy outside Self::backend_from_cluster_id and needs its jitter.

Source

pub fn remove_cluster(&mut self, cluster_id: &str)

Forget everything the map holds for cluster_id: its backend list, with the load-balancing policy and shuffle sharding it carries, its health-check configuration and its http2 hint. A session that already holds one of its backends keeps it until the session closes; Self::close_backend_connection ignores a cluster that is gone. Every backend it drops is marked Closing, as BackendList::remove_backend marks the ones it drops, so a connection pooled on it drains the requests it carries and takes no new one, even once a cluster of the same id is added again.

Source

pub fn set_cluster_http2(&mut self, cluster_id: &str, http2: bool)

Record (or clear) the cluster.http2 backend-capability hint for cluster_id. The health checker reads the resulting map at probe time so the wire format follows what the mux router will use to connect to the same backends.

Source

pub fn set_protected_health_check( &mut self, cluster_id: &str, config: HealthCheckConfig, headers: ProtectedHeaderSet, )

Replace the configuration and the values behind its headers as one step: both change or neither does. A probe already in flight composed its request from the previous set and is not affected.

Source

pub fn restore_health_check( &mut self, cluster_id: &str, config: Option<HealthCheckConfig>, headers: Option<ProtectedHeaderSet>, )

Put back exactly what a protected health check replaced: the configuration and the values behind its headers, each present or absent as it was.

Source

pub fn set_health_check_config( &mut self, cluster_id: &str, config: Option<HealthCheckConfig>, )

Source

pub fn import_configuration_state( &mut self, backends: &HashMap<ClusterId, Vec<Backend>>, )

Source

pub fn add_backend(&mut self, cluster_id: &str, backend: Backend)

Source

pub fn remove_backend( &mut self, cluster_id: &str, backend_id: &str, backend_address: &SocketAddr, ) -> bool

Remove the backend identified by (backend_id, backend_address) from cluster_id and return whether it was present. A backend of another id at the same address stays (#1821).

Source

pub fn close_backend_connection(&mut self, cluster_id: &str, addr: &SocketAddr)

Source

pub fn has_backend_id(&self, cluster_id: &str, backend_id: &str) -> bool

Whether cluster_id still holds a backend carrying backend_id, at any address. Backend metrics are labelled by id alone, so every entry sharing an id feeds one metrics row.

Source

pub fn has_backend(&self, cluster_id: &str, backend: &Backend) -> bool

Source

pub fn backend_from_cluster_id( &mut self, cluster_id: &str, key: Option<u64>, now: Instant, ) -> Result<(Rc<RefCell<Backend>>, TcpStream), BackendError>

Select a backend of cluster_id at now and connect to it.

The TCP proxy’s entry point: it selects and connects in one call, and Backend::try_connect counts the connection once it is established. The HTTP mux reserves with Self::reserve_backend instead and connects on its own side.

key is the client’s affinity key, which HRW and MAGLEV pin the client on and every other policy ignores: the HTTP, HTTPS and TCP datapaths pass the one they derived for a cluster using either policy, and None otherwise (see BackendList::next_available_backend_with_key).

Source

pub fn reserve_backend( &mut self, cluster_id: &str, key: Option<u64>, now: Instant, ) -> Result<Rc<RefCell<Backend>>, BackendError>

Select a backend of cluster_id at now and reserve a connection on it, without connecting (#1684).

The reservation is active_connections += 1, taken under the same borrow as the choice, so the next selection weighs it exactly as it weighed the connection Backend::try_connect used to count at the dial. The caller connects. A connect(2) that fails releases the reservation through Backend::release_failed_dial, which also records the failure. A dial that connects but is abandoned before its connection is registered releases it with a plain Backend::dec_connections, recording no failure (the mux’s BackendChange::ConnectionClosed, #1713). A connection that starts keeps it, and its close releases it like any other.

key is the client’s affinity key, as for Self::backend_from_cluster_id.

Source

pub fn reserve_backend_excluding( &mut self, cluster_id: &str, key: Option<u64>, now: Instant, exclude: &[SocketAddr], ) -> Result<Rc<RefCell<Backend>>, BackendError>

Self::reserve_backend, preferring a backend whose address is not in exclude: the backends a request already failed to connect to (sozu-proxy/sozu#1800). See BackendList::select_with_key_excluding for what happens when every selectable backend is excluded.

Source

pub fn reserve_sticky_backend( &mut self, cluster_id: &str, sticky_session: &str, key: Option<u64>, now: Instant, ) -> Result<Rc<RefCell<Backend>>, BackendError>

Reserve a connection on the backend of cluster_id that sticky_session names, if it can take one at now, falling back to Self::reserve_backend under the client’s affinity key.

A cookie naming a live backend wins over the key: the key only decides where a client without a usable cookie lands.

Source

pub fn reserve_sticky_backend_excluding( &mut self, cluster_id: &str, sticky_session: &str, key: Option<u64>, now: Instant, exclude: &[SocketAddr], ) -> Result<Rc<RefCell<Backend>>, BackendError>

Self::reserve_sticky_backend, except that a cookie naming a backend in exclude is not followed: the request already failed to connect to it, so it goes to Self::reserve_backend_excluding instead (sozu-proxy/sozu#1800).

Source

pub fn backend_from_cluster_id_with_key( &mut self, cluster_id: &str, key: Option<u64>, now: Instant, ) -> Result<(String, SocketAddr), BackendError>

Select a backend for cluster_id, optionally pinned by an affinity key, and return its (backend_id, address) without opening any connection.

This is the UDP datapath’s selection entry point. Unlike backend_from_cluster_id — which is TCP-specific because it calls Backend::try_connect and hands back a TcpStream — UDP owns its own per-flow connected UdpSocket (created in the shell via socket::udp_connect), so all the map needs to surface is the chosen endpoint identity. key is Some(flow_hash) so HRW/Maglev keep a client flow pinned to one backend; None behaves like the legacy round-robin selection. Fail-open (all-unhealthy ⇒ LB over the full set) is inherited from BackendList::next_available_backend_with_key.

Source

pub fn set_load_balancing_policy_for_cluster( &mut self, cluster_id: &str, lb_algo: LoadBalancingAlgorithms, metric: Option<LoadMetric>, )

Source

pub fn set_shuffle_sharding_for_cluster( &mut self, cluster_id: &str, shuffle_sharding: Option<ShuffleSharding>, )

Set or clear the shuffle sharding of cluster_id, creating its backend list if the cluster’s backends have not arrived yet, as Self::set_load_balancing_policy_for_cluster does.

Source

pub fn get_or_create_backend_list_for_cluster( &mut self, cluster_id: &str, ) -> &mut BackendList

Trait Implementations§

Source§

impl BackendSource for BackendMap

The worker’s backend registry, seen by the UDP core as a selection view.

UdpManager selects inside the core now (#1340, Question 6) and reaches the registry only through this, for the duration of one admission. It delegates to BackendMap::backend_from_cluster_id_with_key, the connection-free selection entry point — the UDP datapath owns its own per-flow UdpSocket, so all the map has to surface is the chosen endpoint’s identity.

Source§

fn select( &mut self, cluster: &str, key: Option<u64>, now: Instant, ) -> Option<(BackendId, SocketAddr)>

Pick a backend for cluster, optionally pinned by affinity key so a client flow stays on one backend under HRW / Maglev. None means the cluster has no backend that can serve, which is the caller’s cue to abort the flow rather than park it. Read more
Source§

impl Debug for BackendMap

Source§

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

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

impl Default for BackendMap

Source§

fn default() -> Self

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<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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