1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Least-used proxy rotation strategy.
use Ordering;
use async_trait;
use crate;
use crate;
/// Selects the healthy proxy with the fewest total requests.
///
/// Ties are broken by position (the first minimum in the slice wins),
/// giving stable and predictable behaviour.
///
/// Runs in O(n) over the healthy candidate slice; suitable for pools of up to
/// ~10,000 proxies.
///
/// # Example
/// ```
/// # tokio_test::block_on(async {
/// use stygian_proxy::strategy::{LeastUsedStrategy, RotationStrategy, ProxyCandidate};
/// use stygian_proxy::types::ProxyMetrics;
/// use std::sync::{Arc, atomic::Ordering};
/// use uuid::Uuid;
///
/// let strategy = LeastUsedStrategy;
/// let busy = Arc::new(ProxyMetrics::default());
/// busy.requests_total.store(100, Ordering::Relaxed);
/// let idle = Arc::new(ProxyMetrics::default());
/// let candidates = vec![
/// ProxyCandidate { id: Uuid::from_u128(1), weight: 1, metrics: busy, healthy: true, capabilities: Default::default() },
/// ProxyCandidate { id: Uuid::from_u128(2), weight: 1, metrics: idle, healthy: true, capabilities: Default::default() },
/// ];
/// let chosen = strategy.select(&candidates).await.unwrap();
/// assert_eq!(chosen.id, Uuid::from_u128(2), "should pick the idle proxy");
/// # })
/// ```
;