load_balancer/lib.rs
1//! # Load Balancer Library
2//!
3//! This library provides a set of generic load balancer implementations for distributing
4//! workloads across multiple targets, such as clients, network endpoints, or resources.
5//!
6//! ## Modules
7//!
8//! - `ip` - Provides IP-based client load balancers with rate-limiting per IP.
9//! - `limit` - Implements a limit-based load balancer that restricts allocations per entry
10//! within a configurable time interval.
11//! - `random` - Randomly selects an entry from the available pool.
12//! - `simple` - A simple sequential load balancer with optional Arc or Mutex wrappers.
13//! - `threshold` - Implements threshold-based load balancing logic.
14//!
15//! ## Traits
16//!
17//! ### `LoadBalancer<T>`
18//!
19//! A generic trait for asynchronous or synchronous load balancing. Implementors provide
20//! methods to allocate a resource from the pool.
21//!
22//! ```rust
23//! use std::future::Future;
24//!
25//! pub trait LoadBalancer<T>: Send + Sync + Clone + 'static {
26//! /// Asynchronously allocate a resource.
27//! /// Returns `Some(T)` if successful, or `None` if no resource is available.
28//! fn alloc(&self) -> impl Future<Output = Option<T>> + Send;
29//!
30//! /// Attempt to allocate a resource synchronously without awaiting.
31//! /// Returns `Some(T)` if successful, or `None` if no resource is available.
32//! fn try_alloc(&self) -> Option<T>;
33//! }
34//! ```
35//!
36//! ### `BoxLoadBalancer<T>`
37//!
38//! An async trait variant that can be used with `async_trait` for boxed trait objects
39//! or dynamic dispatch. Provides similar functionality to `LoadBalancer` but supports
40//! fully `async` method signatures.
41//!
42//! ```rust
43//! use async_trait::async_trait;
44//!
45//! #[async_trait]
46//! pub trait BoxLoadBalancer<T>: Send + Sync + Clone + 'static {
47//! /// Asynchronously allocate a resource.
48//! /// Returns `Some(T)` if successful, or `None` if no resource is available.
49//! async fn alloc(&self) -> Option<T>;
50//!
51//! /// Attempt to allocate a resource synchronously without awaiting.
52//! /// Returns `Some(T)` if successful, or `None` if no resource is available.
53//! fn try_alloc(&self) -> Option<T>;
54//! }
55//! ```
56//!
57//! ## Usage Example
58//!
59//! ```rust
60//! use your_crate::random::RandomLoadBalancer;
61//!
62//! #[tokio::main]
63//! async fn main() {
64//! let lb = RandomLoadBalancer::new(vec![1, 2, 3]);
65//! if let Some(value) = lb.alloc().await {
66//! println!("Allocated value: {}", value);
67//! }
68//! }
69//! ```
70//!
71//! ## Notes
72//!
73//! - All load balancers are `Send`, `Sync`, and `Clone`, making them suitable for multi-threaded
74//! asynchronous environments.
75//! - The `alloc` method returns `Option<T>` rather than `Result`, reflecting that allocation
76//! failure is expected under normal conditions and not necessarily an error.
77//! - `try_alloc` is non-blocking and will return `None` immediately if no resource is available.
78
79pub mod ip;
80pub mod limit;
81pub mod random;
82pub mod simple;
83pub mod threshold;
84pub use anyhow;
85pub use get_if_addrs;
86
87use async_trait::async_trait;
88use std::future::Future;
89
90pub trait LoadBalancer<T>: Send + Sync + Clone + 'static {
91 fn alloc(&self) -> impl Future<Output = T> + Send;
92 fn try_alloc(&self) -> Option<T>;
93}
94
95#[async_trait]
96pub trait BoxLoadBalancer<T>: Send + Sync + Clone + 'static {
97 async fn alloc(&self) -> T;
98 fn try_alloc(&self) -> Option<T>;
99}