cakerabbit_core/
selector.rs

1
2use crate::CakeResult;
3use rand::{ distributions::uniform, Rng };
4use rand::distributions::Uniform;
5use serde::{Serialize, Deserialize};
6
7pub trait Selector {
8  fn select(&mut self) -> String;
9  fn update_serv_nodes(&mut self, serv_new_nodes: Vec<String>) -> CakeResult<bool>;
10}
11
12#[derive(Clone, Serialize, Deserialize)]
13pub enum SelectorTyp {
14  Random,
15  RoundRobin,
16}
17
18pub fn new_selector(st: &SelectorTyp, serv_nodes: Vec<String>) -> Box<dyn Selector> {
19  return match st {
20    SelectorTyp::RoundRobin => {
21      trace!("--- choose RoundRobinSelect ---");
22      Box::new(RoundRobinSelect::new(serv_nodes))
23    },
24    SelectorTyp::Random => {
25      trace!("--- choose RandomSelect ---");
26      Box::new(RandomSelect::new(serv_nodes))
27    }
28  }
29}
30
31// -----------------------------------------------------------------------
32
33struct RandomSelect {
34  pub serv_nodes:   Vec<String>,
35}
36
37impl RandomSelect {
38  fn new(serv_nodes: Vec<String>) -> Self {
39    RandomSelect{ serv_nodes }
40  }
41}
42
43impl Selector for RandomSelect {
44  fn select(&mut self) -> String {
45
46    let serv_nodes_len = self.serv_nodes.len();
47    if serv_nodes_len == 0 {
48      return "".to_string();
49    }
50    let mut rng = rand::thread_rng();
51    let range = Uniform::new(0, serv_nodes_len);
52    let random_num = rng.sample(&range);
53    let node = self.serv_nodes.get(random_num).unwrap();
54    node.to_string()
55  }
56
57  fn update_serv_nodes(&mut self, serv_new_nodes: Vec<String>) -> CakeResult<bool> {
58    self.serv_nodes = serv_new_nodes;
59    Ok(true)
60  }
61}
62
63// -----------------------------------------------------------------------
64
65struct RoundRobinSelect {
66  serv_nodes:   Vec<String>,
67  round_index:  usize,
68}
69
70impl RoundRobinSelect {
71  fn new(serv_nodes: Vec<String>) -> Self {
72    RoundRobinSelect{ serv_nodes, round_index: 0 }
73  }
74}
75
76impl Selector for RoundRobinSelect {
77  fn select(&mut self) -> String {
78    let serv_nodes_len = self.serv_nodes.len();
79    if serv_nodes_len == 0 {
80      return "".to_string();
81    }
82
83    let mut index = self.round_index;
84    index = index % serv_nodes_len;
85    trace!("index -->>> {}", index);
86    let node = self.serv_nodes.get(index).unwrap();
87    self.round_index = index + 1;
88    node.to_string()
89  }
90
91  fn update_serv_nodes(&mut self, serv_new_nodes: Vec<String>) -> CakeResult<bool> {
92    self.serv_nodes = serv_new_nodes;
93    Ok(true)
94  }
95}
96
97
98mod tests {
99  #![feature(impl_trait_in_bindings)]
100  use rand::{ distributions::uniform, Rng };
101  use rand::distributions::Uniform;
102  use super::*;
103  use std::time;
104  use std::thread;
105
106  #[test]
107  fn test_random_selector() {
108    let mut rng = rand::thread_rng();
109    let range = Uniform::new(0, 5);
110    let x = rng.sample(&range);
111    trace!("random i32 -->>> {}", x);
112
113    let mut selector = new_selector(&SelectorTyp::Random,
114                                    vec!["8.8.8.8:90".to_string(),
115                                         "7.7.7.7:99".to_string(), "6.6.6.6:88".to_string()]);
116    let node = selector.select();
117    trace!("node -->>> {}", node);
118
119    let new_nodes = vec!["1.1.1.1:33".to_string(), "2.2.2.2:55".to_string()];
120    let ok = selector.update_serv_nodes(new_nodes);
121    trace!("ok -->>> {:?}", ok);
122    let node1 = selector.select();
123    trace!("node1 -->>> {}", node1);
124  }
125
126  #[test]
127  fn test_roundrobin_selector() {
128    let mut selector = new_selector(&SelectorTyp::RoundRobin,
129                                    vec!["8.8.8.8:90".to_string(),
130                                         "7.7.7.7:99".to_string(), "6.6.6.6:88".to_string()]);
131    let node1 = selector.select();
132    trace!("node1 -->>> {}", node1);
133
134    thread::sleep(time::Duration::from_secs(1));
135    let node2 = selector.select();
136    trace!("node2 -->>> {}", node2);
137
138    thread::sleep(time::Duration::from_secs(1));
139    let node3 = selector.select();
140    trace!("node3 -->>> {}", node3);
141
142    thread::sleep(time::Duration::from_secs(1));
143    let node4 = selector.select();
144    trace!("node4 -->>> {}", node4);
145  }
146}
147
148
149
150