loadwise-core 0.1.0

Core traits, strategies, and in-memory stores for loadwise
Documentation
//! Traits for describing backend nodes and their observable properties.

use std::fmt::Debug;
use std::hash::Hash;

/// A backend node that can be selected by a load balancing strategy.
pub trait Node: Send + Sync {
    /// Unique identifier type for this node.
    type Id: Eq + Hash + Clone + Debug + Send + Sync;

    /// Returns a reference to this node's unique identifier.
    fn id(&self) -> &Self::Id;
}

/// Exposes a weight for weighted strategies. Higher weight = more traffic.
pub trait Weighted: Send + Sync {
    /// Relative weight of this node. A node with weight 4 receives roughly
    /// twice the traffic of a node with weight 2.
    fn weight(&self) -> u32;
}

/// Exposes a load score for load-aware strategies. Lower is better.
pub trait LoadMetric: Send + Sync {
    /// Current load score. Strategies like [`LeastLoad`](crate::strategy::LeastLoad)
    /// and [`PowerOfTwoChoices`](crate::strategy::PowerOfTwoChoices) use this to
    /// prefer less-loaded nodes.
    ///
    /// Should return a finite, non-NaN value. With [`LeastLoad`](crate::strategy::LeastLoad),
    /// a NaN node is never selected (`NaN < x` is always `false`).
    /// With [`PowerOfTwoChoices`](crate::strategy::PowerOfTwoChoices), a NaN node **may**
    /// be selected because P2C uses `<=` (`x <= NaN` is `false`, causing the NaN node
    /// to win the comparison).
    fn load_score(&self) -> f64;
}

/// Exposes remaining capacity for quota-aware strategies. Higher is better.
///
/// Complementary to [`LoadMetric`] (which exposes current load — lower is better):
/// - `LoadMetric`: "how busy is this node?" → lower wins
/// - `RateMetric`: "how much capacity remains?" → higher wins
///
/// A node can implement both — a node may have low load but little remaining
/// quota, or high load but ample quota.
pub trait RateMetric: Send + Sync {
    /// Remaining capacity as a ratio: `0.0` = exhausted, `1.0` = fully available.
    fn remaining_ratio(&self) -> f64;
}