wd_balancing 0.0.4

A practical load balancing library for rust
Documentation
use crate::{BalancingCall,BalancingStrategy,Linker,Polling};
use std::sync::Arc;
use std::collections::HashMap;
use tokio::sync::RwLock;
use std::ops::DerefMut;
use std::hash::Hash;



pub struct Balancing<K,Req, Res>{
    map:RwLock<HashMap<K,Box<dyn BalancingCall<Req, Res>+Send+Sync>>>,
    strategy:Arc<dyn BalancingStrategy<K> + Send + Sync>,
    linker:Option<Arc<dyn Linker<K> + Send + Sync>>,
}
impl<K:Clone + Eq + Hash + Send + Sync + 'static ,Req, Res> Balancing<K,Req, Res>{
    pub fn new()->Self{
        let map = RwLock::new(HashMap::new());
        let strategy = Arc::new(Polling::<K>::new());
        let linker = None;
        Self{map,strategy,linker}
    }
    pub fn set_strategy<B>(mut self, strategy:B) ->Self
        where B:BalancingStrategy<K> + Send + Sync + 'static
    {
        let strategy = Arc::new(strategy);
        self.strategy = strategy;
        self
    }
    pub fn set_strategy_linker<B>(mut self,strategy:B)->Self
        where B:BalancingStrategy<K>+Linker<K> + Send + Sync + 'static
    {
        let strategy = Arc::new(strategy);
        self.strategy = strategy.clone();
        self.linker = Some(strategy);
        self
    }

    pub async fn add<N:BalancingCall<Req, Res>+Send+Sync+'static>(&self,key:K,n:N,w:usize){
        if w <= 0{
            return;
        }
        let mut map = self.map.write().await;
        let map = map.deref_mut();
        map.insert(key.clone(),Box::new(n));
        self.strategy.add(key,w).await;
    }
    pub async fn remove(&self, key:K) -> Option<Box<dyn BalancingCall<Req, Res>+Send+Sync>> {
        let mut map = self.map.write().await;
        let map = map.deref_mut();
        let res = map.remove(&key);
        self.strategy.remove(key).await;
        res
    }
    pub async fn call(&self,reqs:Req)->Option<Res>{
        let mut resp = None;
        let map = self.map.read().await;
        if let Some(k) = self.strategy.select().await {

            if let Some(node) = map.get(&k) {
                if let Some(ref s) = self.linker {
                    s.acquire(k.clone()).await
                }

                resp = node.call(reqs).await;

                if let Some(ref s) = self.linker {
                    s.release(k).await
                }
            }
        }
        resp
    }
}