Skip to main content

sz_orm_core/
degradation.rs

1//! v7.5.0 降级路径执行器(feature gate: `circuit-breaker`,默认关闭)
2//!
3//! 当 `CircuitBreaker::can_execute() == false` 时调用 `DegradationHandler::handle()`,
4//! 提供缓存降级 / 默认值降级 / 快速失败三种策略。
5
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
9pub enum DegradationStrategy {
10    ReturnCache,
11    ReturnDefault,
12    FastFail,
13}
14
15impl DegradationStrategy {
16    pub fn as_str(&self) -> &'static str {
17        match self {
18            DegradationStrategy::ReturnCache => "return_cache",
19            DegradationStrategy::ReturnDefault => "return_default",
20            DegradationStrategy::FastFail => "fast_fail",
21        }
22    }
23}
24
25#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
26pub struct DegradationResult {
27    pub data: Option<Vec<HashMap<String, String>>>,
28    pub is_degraded: bool,
29    pub degradation_strategy: DegradationStrategy,
30    pub mismatch_warning: bool,
31}
32
33impl DegradationResult {
34    pub fn from_cache(data: Vec<HashMap<String, String>>) -> Self {
35        Self {
36            data: Some(data),
37            is_degraded: true,
38            degradation_strategy: DegradationStrategy::ReturnCache,
39            mismatch_warning: false,
40        }
41    }
42
43    pub fn from_default() -> Self {
44        Self {
45            data: Some(Vec::new()),
46            is_degraded: true,
47            degradation_strategy: DegradationStrategy::ReturnDefault,
48            mismatch_warning: false,
49        }
50    }
51
52    pub fn fast_fail() -> Self {
53        Self {
54            data: None,
55            is_degraded: true,
56            degradation_strategy: DegradationStrategy::FastFail,
57            mismatch_warning: false,
58        }
59    }
60
61    pub fn with_mismatch_warning(mut self) -> Self {
62        self.mismatch_warning = true;
63        self
64    }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
68pub enum DegradationError {
69    #[error("cache miss for query fingerprint: {0}")]
70    CacheMiss(String),
71    #[error("fast fail: circuit breaker open")]
72    FastFail,
73    #[error("degradation data mismatch for query fingerprint: {0}")]
74    DataMismatch(String),
75}
76
77pub trait DegradationHandler: Send + Sync {
78    fn handle(&self, query_fingerprint: &str) -> Result<DegradationResult, DegradationError>;
79    fn strategy(&self) -> DegradationStrategy;
80}
81
82pub struct CacheDegradation {
83    cache: HashMap<String, Vec<HashMap<String, String>>>,
84}
85
86impl CacheDegradation {
87    /// 创建空的缓存降级处理器。
88    pub fn new() -> Self {
89        Self {
90            cache: HashMap::new(),
91        }
92    }
93
94    pub fn with_cache(cache: HashMap<String, Vec<HashMap<String, String>>>) -> Self {
95        Self { cache }
96    }
97
98    pub fn insert(&mut self, fingerprint: String, data: Vec<HashMap<String, String>>) {
99        self.cache.insert(fingerprint, data);
100    }
101}
102
103impl Default for CacheDegradation {
104    fn default() -> Self {
105        Self::new()
106    }
107}
108
109impl DegradationHandler for CacheDegradation {
110    fn handle(&self, query_fingerprint: &str) -> Result<DegradationResult, DegradationError> {
111        match self.cache.get(query_fingerprint) {
112            Some(data) => Ok(DegradationResult::from_cache(data.clone())),
113            None => Err(DegradationError::CacheMiss(query_fingerprint.to_string())),
114        }
115    }
116
117    fn strategy(&self) -> DegradationStrategy {
118        DegradationStrategy::ReturnCache
119    }
120}
121
122pub struct DefaultDegradation;
123
124impl DefaultDegradation {
125    pub fn new() -> Self {
126        Self
127    }
128}
129
130impl Default for DefaultDegradation {
131    fn default() -> Self {
132        Self
133    }
134}
135
136impl DegradationHandler for DefaultDegradation {
137    fn handle(&self, _query_fingerprint: &str) -> Result<DegradationResult, DegradationError> {
138        Ok(DegradationResult::from_default())
139    }
140
141    fn strategy(&self) -> DegradationStrategy {
142        DegradationStrategy::ReturnDefault
143    }
144}
145
146pub struct FastFailDegradation;
147
148impl FastFailDegradation {
149    pub fn new() -> Self {
150        Self
151    }
152}
153
154impl Default for FastFailDegradation {
155    fn default() -> Self {
156        Self
157    }
158}
159
160impl DegradationHandler for FastFailDegradation {
161    fn handle(&self, _query_fingerprint: &str) -> Result<DegradationResult, DegradationError> {
162        Err(DegradationError::FastFail)
163    }
164
165    fn strategy(&self) -> DegradationStrategy {
166        DegradationStrategy::FastFail
167    }
168}
169
170/// 在断路器拦截时执行降级路径,正常时执行原始查询。
171pub fn execute_with_degradation(
172    can_execute: bool,
173    handler: &dyn DegradationHandler,
174    query_fingerprint: &str,
175    normal_query: impl FnOnce() -> Result<Vec<HashMap<String, String>>, String>,
176) -> Result<DegradationResult, DegradationError> {
177    if can_execute {
178        match normal_query() {
179            Ok(data) => Ok(DegradationResult {
180                data: Some(data),
181                is_degraded: false,
182                degradation_strategy: handler.strategy(),
183                mismatch_warning: false,
184            }),
185            Err(_) => handler.handle(query_fingerprint),
186        }
187    } else {
188        handler.handle(query_fingerprint)
189    }
190}