1use detcd::{DestinationRule, Service, Strategy};
2use http_pool::net_pool::{Address, Pool, Pools};
3use std::sync::Arc;
4
5pub trait PoolsExt {
6 fn add_service(&self, service: &Service) -> bool;
8
9 fn remove_service(&self, service: &Service) -> bool;
11}
12
13impl<P: Pool + Default> PoolsExt for Pools<P> {
14 fn add_service(&self, service: &Service) -> bool {
15 let pool = match self.get_pool(&service.key.name) {
16 Some(p) => Some(p),
17 None => {
18 if let Some(ref meta) = service.meta {
20 let mut pool = P::default();
21 let strategy = new_strategy_by_rule(&meta.destination_rule);
22 pool.set_strategy(strategy);
24 pool.set_id(&service.key.name);
26 pool.use_tls(service.meta.as_ref().unwrap().tls.map_or(false, |t| t));
28 let pool = Arc::new(pool);
29 self.add_arc_pool(pool.clone());
30 Some(pool)
31 } else {
32 None
33 }
34 }
35 };
36
37 if let Some(p) = pool {
38 p.add_backend(service.key.id, Address::from(service.address()));
39 true
40 } else {
41 false
42 }
43 }
44
45 fn remove_service(&self, service: &Service) -> bool {
46 if let Some(pool) = self.get_pool(&service.key.name) {
47 pool.remove_backend(&Address::from(service.address()))
48 } else {
49 false
50 }
51 }
52}
53
54pub fn new_strategy(strategy: &Strategy) -> Arc<dyn http_pool::net_pool::Strategy> {
56 match strategy {
57 Strategy::Hash => Arc::new(http_pool::net_pool::HashStrategy::new()),
58 Strategy::ConsistentHash => Arc::new(http_pool::net_pool::CHStrategy::new(256)),
59 Strategy::RoundRobin => Arc::new(http_pool::net_pool::RRStrategy::new()),
60 }
61}
62
63pub fn new_strategy_by_rule(rule: &DestinationRule) -> Arc<dyn http_pool::net_pool::Strategy> {
64 match rule {
65 DestinationRule::Header(_, strategy) => new_strategy(strategy),
66 DestinationRule::Path(strategy) => new_strategy(strategy),
67 }
68}