use detcd::{DestinationRule, Service, Strategy};
use http_pool::net_pool::{Address, Pool, Pools};
use std::sync::Arc;
pub trait PoolsExt {
fn add_service(&self, service: &Service) -> bool;
fn remove_service(&self, service: &Service) -> bool;
}
impl<P: Pool + Default> PoolsExt for Pools<P> {
fn add_service(&self, service: &Service) -> bool {
let pool = match self.get_pool(&service.key.name) {
Some(p) => Some(p),
None => {
if let Some(ref meta) = service.meta {
let mut pool = P::default();
let strategy = new_strategy_by_rule(&meta.destination_rule);
pool.set_strategy(strategy);
pool.set_id(&service.key.name);
pool.use_tls(service.meta.as_ref().unwrap().tls.map_or(false, |t| t));
let pool = Arc::new(pool);
self.add_arc_pool(pool.clone());
Some(pool)
} else {
None
}
}
};
if let Some(p) = pool {
p.add_backend(service.key.id, Address::from(service.address()));
true
} else {
false
}
}
fn remove_service(&self, service: &Service) -> bool {
if let Some(pool) = self.get_pool(&service.key.name) {
pool.remove_backend(&Address::from(service.address()))
} else {
false
}
}
}
pub fn new_strategy(strategy: &Strategy) -> Arc<dyn http_pool::net_pool::Strategy> {
match strategy {
Strategy::Hash => Arc::new(http_pool::net_pool::HashStrategy::new()),
Strategy::ConsistentHash => Arc::new(http_pool::net_pool::CHStrategy::new(256)),
Strategy::RoundRobin => Arc::new(http_pool::net_pool::RRStrategy::new()),
}
}
pub fn new_strategy_by_rule(rule: &DestinationRule) -> Arc<dyn http_pool::net_pool::Strategy> {
match rule {
DestinationRule::Header(_, strategy) => new_strategy(strategy),
DestinationRule::Path(strategy) => new_strategy(strategy),
}
}