route-util 0.1.0

route utils
Documentation
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);
                    // 设置strategy
                    pool.set_strategy(strategy);
                    // 设置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
                }
            }
        };

        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),
    }
}