fusen-rs 0.8.11

RPC framework for service registration and discovery through API exposure, compatible with Dubbo3 protocol, intertunable with Java projects
Documentation
use crate::{
    error::FusenError,
    filter::FusenFilter,
    handler::{
        aspect::DefaultAspect,
        loadbalance::{DefaultLoadBalance, LoadBalance_},
    },
    protocol::fusen::service::ServiceDesc,
};
use std::{collections::HashMap, sync::Arc};

pub mod aspect;
pub mod loadbalance;

#[derive(Clone)]
pub struct HandlerController {
    pub load_balance: Option<Arc<Box<dyn LoadBalance_>>>,
    pub aspect: Arc<Vec<Arc<Box<dyn FusenFilter>>>>,
}

pub enum HandlerInvoker {
    LoadBalance(Arc<Box<dyn LoadBalance_>>),
    Aspect(Arc<Box<dyn FusenFilter>>),
}

pub struct HandlerContext {
    handlers: HashMap<String, Arc<HandlerInvoker>>,
    cache: HashMap<String, HandlerController>,
}

pub struct HandlerInfo {
    pub service_desc: ServiceDesc,
    pub handlers: Vec<String>,
}

impl Default for HandlerContext {
    fn default() -> Self {
        let mut context = Self {
            handlers: Default::default(),
            cache: Default::default(),
        };
        context.handlers.insert(
            "DefaultLoadBalance".to_string(),
            Arc::new(HandlerInvoker::LoadBalance(Arc::new(Box::new(
                DefaultLoadBalance,
            )))),
        );
        context.handlers.insert(
            "DefaultAspect".to_string(),
            Arc::new(HandlerInvoker::Aspect(Arc::new(Box::new(DefaultAspect)))),
        );
        context.load_controller(HandlerInfo {
            service_desc: ServiceDesc::new("DefaultHandlerController", None, None),
            handlers: vec![],
        });
        context
    }
}

impl HandlerContext {
    pub fn load_handler(&mut self, handler: Handler) {
        self.handlers
            .insert(handler.id, Arc::new(handler.handler_invoker));
    }

    pub fn get_controller(
        &self,
        service_desc: &ServiceDesc,
    ) -> Result<&HandlerController, FusenError> {
        Ok(self.cache.get(service_desc.get_tag()).unwrap_or(
            self.cache.get("DefaultHandlerController:None:None").ok_or(
                FusenError::ErrorMessage("get DefaultHandlerController error"),
            )?,
        ))
    }

    pub fn load_controller(&mut self, handler_info: HandlerInfo) {
        let mut load_balance: Option<Arc<Box<dyn LoadBalance_>>> = None;
        let mut aspect: Vec<Arc<Box<dyn FusenFilter>>> = Vec::new();
        for handler_id in &handler_info.handlers {
            if let Some(handler_invoker) = self.get_handler(handler_id) {
                match handler_invoker.as_ref() {
                    HandlerInvoker::LoadBalance(handler) => {
                        let _ = load_balance.insert(handler.clone());
                    }
                    HandlerInvoker::Aspect(handler) => {
                        aspect.push(handler.clone());
                    }
                };
            }
        }
        if load_balance.is_none()
            && let Some(handler_invoker) = self.get_handler("DefaultLoadBalance")
        {
            match handler_invoker.as_ref() {
                HandlerInvoker::LoadBalance(handler) => load_balance.insert(handler.clone()),
                _ => panic!("{}", FusenError::Impossible),
            };
        }

        let handler_controller = HandlerController {
            load_balance,
            aspect: Arc::new(aspect),
        };
        self.cache.insert(
            handler_info.service_desc.get_tag().to_owned(),
            handler_controller,
        );
    }

    fn get_handler(&self, handler_id: &str) -> Option<Arc<HandlerInvoker>> {
        self.handlers.get(handler_id).cloned()
    }
}

pub struct Handler {
    pub id: String,
    pub handler_invoker: HandlerInvoker,
}

pub trait HandlerLoad {
    fn load(self) -> Handler;
}