service-pool-util 0.1.1

服务连接池辅助
Documentation
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();
                    // 设置strategy
                    pool.set_strategy(new_strategy_by_rule(&meta.destination_rule));
                    // 设置id
                    pool.set_id(&service.key.name);
                    // 设置tls
                    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),
    }
}