sz-orm-core 7.6.0

Core ORM engine: Model trait, ActiveRecord, QueryBuilder, Pool, Transaction, migration, and SQL dialect abstraction
Documentation
//! v7.5.0 降级路径执行器(feature gate: `circuit-breaker`,默认关闭)
//!
//! 当 `CircuitBreaker::can_execute() == false` 时调用 `DegradationHandler::handle()`,
//! 提供缓存降级 / 默认值降级 / 快速失败三种策略。

use std::collections::HashMap;

#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum DegradationStrategy {
    ReturnCache,
    ReturnDefault,
    FastFail,
}

impl DegradationStrategy {
    pub fn as_str(&self) -> &'static str {
        match self {
            DegradationStrategy::ReturnCache => "return_cache",
            DegradationStrategy::ReturnDefault => "return_default",
            DegradationStrategy::FastFail => "fast_fail",
        }
    }
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DegradationResult {
    pub data: Option<Vec<HashMap<String, String>>>,
    pub is_degraded: bool,
    pub degradation_strategy: DegradationStrategy,
    pub mismatch_warning: bool,
}

impl DegradationResult {
    pub fn from_cache(data: Vec<HashMap<String, String>>) -> Self {
        Self {
            data: Some(data),
            is_degraded: true,
            degradation_strategy: DegradationStrategy::ReturnCache,
            mismatch_warning: false,
        }
    }

    pub fn from_default() -> Self {
        Self {
            data: Some(Vec::new()),
            is_degraded: true,
            degradation_strategy: DegradationStrategy::ReturnDefault,
            mismatch_warning: false,
        }
    }

    pub fn fast_fail() -> Self {
        Self {
            data: None,
            is_degraded: true,
            degradation_strategy: DegradationStrategy::FastFail,
            mismatch_warning: false,
        }
    }

    pub fn with_mismatch_warning(mut self) -> Self {
        self.mismatch_warning = true;
        self
    }
}

#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum DegradationError {
    #[error("cache miss for query fingerprint: {0}")]
    CacheMiss(String),
    #[error("fast fail: circuit breaker open")]
    FastFail,
    #[error("degradation data mismatch for query fingerprint: {0}")]
    DataMismatch(String),
}

pub trait DegradationHandler: Send + Sync {
    fn handle(&self, query_fingerprint: &str) -> Result<DegradationResult, DegradationError>;
    fn strategy(&self) -> DegradationStrategy;
}

pub struct CacheDegradation {
    cache: HashMap<String, Vec<HashMap<String, String>>>,
}

impl CacheDegradation {
    /// 创建空的缓存降级处理器。
    pub fn new() -> Self {
        Self {
            cache: HashMap::new(),
        }
    }

    pub fn with_cache(cache: HashMap<String, Vec<HashMap<String, String>>>) -> Self {
        Self { cache }
    }

    pub fn insert(&mut self, fingerprint: String, data: Vec<HashMap<String, String>>) {
        self.cache.insert(fingerprint, data);
    }
}

impl Default for CacheDegradation {
    fn default() -> Self {
        Self::new()
    }
}

impl DegradationHandler for CacheDegradation {
    fn handle(&self, query_fingerprint: &str) -> Result<DegradationResult, DegradationError> {
        match self.cache.get(query_fingerprint) {
            Some(data) => Ok(DegradationResult::from_cache(data.clone())),
            None => Err(DegradationError::CacheMiss(query_fingerprint.to_string())),
        }
    }

    fn strategy(&self) -> DegradationStrategy {
        DegradationStrategy::ReturnCache
    }
}

pub struct DefaultDegradation;

impl DefaultDegradation {
    pub fn new() -> Self {
        Self
    }
}

impl Default for DefaultDegradation {
    fn default() -> Self {
        Self
    }
}

impl DegradationHandler for DefaultDegradation {
    fn handle(&self, _query_fingerprint: &str) -> Result<DegradationResult, DegradationError> {
        Ok(DegradationResult::from_default())
    }

    fn strategy(&self) -> DegradationStrategy {
        DegradationStrategy::ReturnDefault
    }
}

pub struct FastFailDegradation;

impl FastFailDegradation {
    pub fn new() -> Self {
        Self
    }
}

impl Default for FastFailDegradation {
    fn default() -> Self {
        Self
    }
}

impl DegradationHandler for FastFailDegradation {
    fn handle(&self, _query_fingerprint: &str) -> Result<DegradationResult, DegradationError> {
        Err(DegradationError::FastFail)
    }

    fn strategy(&self) -> DegradationStrategy {
        DegradationStrategy::FastFail
    }
}

/// 在断路器拦截时执行降级路径,正常时执行原始查询。
pub fn execute_with_degradation(
    can_execute: bool,
    handler: &dyn DegradationHandler,
    query_fingerprint: &str,
    normal_query: impl FnOnce() -> Result<Vec<HashMap<String, String>>, String>,
) -> Result<DegradationResult, DegradationError> {
    if can_execute {
        match normal_query() {
            Ok(data) => Ok(DegradationResult {
                data: Some(data),
                is_degraded: false,
                degradation_strategy: handler.strategy(),
                mismatch_warning: false,
            }),
            Err(_) => handler.handle(query_fingerprint),
        }
    } else {
        handler.handle(query_fingerprint)
    }
}