Skip to main content

satex_load_balancer/selector/
mod.rs

1mod algorithm;
2mod consistent;
3mod weighted;
4
5use crate::selector::weighted::Weighted;
6use crate::Backend;
7use std::collections::BTreeSet;
8
9/// Random selection on weighted backends
10pub type Random = Weighted<algorithm::Random>;
11
12/// Round-robin selection on weighted backends
13pub type RoundRobin = Weighted<algorithm::RoundRobin>;
14
15/// Consistent Ketama hashing on weighted backends
16pub type Consistent = consistent::KetamaHashing;
17
18pub trait BackendIter {
19    fn next(&mut self) -> Option<&Backend>;
20}
21
22pub struct BoxBackendIter(Box<dyn BackendIter + Send + Sync>);
23
24impl BackendIter for BoxBackendIter {
25    fn next(&mut self) -> Option<&Backend> {
26        self.0.next()
27    }
28}
29
30pub trait Selector {
31    type Iter: BackendIter;
32
33    fn update(&self, backends: &BTreeSet<Backend>);
34
35    fn iter(&self, key: &[u8]) -> Self::Iter;
36}
37
38pub(crate) struct Map<S>(S);
39
40impl<S> Map<S> {
41    pub fn new(selector: S) -> Self {
42        Self(selector)
43    }
44}
45
46impl<S> Selector for Map<S>
47where
48    S: Selector + Send + Sync,
49    S::Iter: Send + Sync + 'static,
50{
51    type Iter = BoxBackendIter;
52
53    fn update(&self, backends: &BTreeSet<Backend>) {
54        self.0.update(backends);
55    }
56
57    fn iter(&self, key: &[u8]) -> Self::Iter {
58        BoxBackendIter(Box::new(self.0.iter(key)))
59    }
60}
61
62pub struct BoxSelector(Box<dyn Selector<Iter = BoxBackendIter> + Send + Sync>);
63
64impl BoxSelector {
65    pub fn new<S>(selector: S) -> Self
66    where
67        S: Selector + Send + Sync + 'static,
68        S::Iter: Send + Sync + 'static,
69    {
70        Self(Box::new(Map::new(selector)))
71    }
72}
73
74impl Selector for BoxSelector {
75    type Iter = BoxBackendIter;
76
77    fn update(&self, backends: &BTreeSet<Backend>) {
78        self.0.update(backends)
79    }
80
81    fn iter(&self, key: &[u8]) -> Self::Iter {
82        self.0.iter(key)
83    }
84}