use detector::{DestinationRule, Service, Strategy};
use net_pool::{Address, Pool, Pools};
use std::sync::Arc;
pub trait PoolsWithService {
fn add_backend_from_service(&self, service: &Service) -> bool;
fn remove_backend_from_service(&self, service: &Service) -> bool;
}
impl<P: Pool + Default> PoolsWithService for Pools<P> {
fn add_backend_from_service(&self, service: &Service) -> bool {
let pool = match self.get_pool(&service.key.name) {
None => {
if let Some(ref meta) = service.meta {
let mut pool = P::default();
pool.set_strategy(new_strategy_by_rule(&meta.destination_rule));
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
}
}
Some(p) => Some(p),
};
if let Some(p) = pool {
p.add_backend(service.key.id, Address::from(service.address()));
true
} else {
false
}
}
fn remove_backend_from_service(&self, service: &Service) -> bool {
match self.get_pool(&service.key.name) {
Some(p) => {
let r = p.remove_backend(&Address::from(service.address()));
if p.get_backends().is_empty() {
self.remove_pool(&service.key.name);
}
r
},
None => false,
}
}
}
pub fn new_strategy(strategy: &Strategy) -> Arc<dyn net_pool::Strategy> {
match strategy {
Strategy::Hash => Arc::new(net_pool::HashStrategy::new()),
Strategy::ConsistentHash => Arc::new(net_pool::CHStrategy::new(256)),
Strategy::RoundRobin => Arc::new(net_pool::RRStrategy::new()),
}
}
pub fn new_strategy_by_rule(rule: &DestinationRule) -> Arc<dyn net_pool::Strategy> {
match rule {
DestinationRule::Header(_, strategy) => new_strategy(strategy),
DestinationRule::Path(strategy) => new_strategy(strategy),
}
}