Skip to main content

grate_limiter/
config.rs

1use serde::{Deserialize, Serialize};
2use std::sync::Arc;
3
4use crate::clock::{self, Clock};
5use crate::health::HealthConfig;
6use crate::scoring::ScoringWeights;
7
8/// Top-level engine configuration.
9#[derive(Clone, Serialize, Deserialize)]
10pub struct EngineConfig {
11    /// Scoring weights for provider selection.
12    pub scoring: ScoringWeights,
13
14    /// Health engine configuration.
15    pub health: HealthConfig,
16
17    /// Minimum health score before a provider is excluded from selection.
18    pub minimum_health_score: f32,
19
20    /// Time (in seconds) that a provider should remain on cooldown after being triggered.
21    pub default_cooldown_seconds: u64,
22
23    /// Internal clock (not serialized). Use [`EngineConfig::with_clock`].
24    #[serde(skip)]
25    pub(crate) clock: Option<Arc<dyn Clock>>,
26}
27
28impl EngineConfig {
29    /// Inject a custom clock (e.g., [`MockClock`](crate::MockClock) for deterministic testing).
30    pub fn with_clock(mut self, clock: Arc<dyn Clock>) -> Self {
31        self.clock = Some(clock);
32        self
33    }
34
35    pub(crate) fn clock(&self) -> Arc<dyn Clock> {
36        self.clock.clone().unwrap_or_else(clock::default_clock)
37    }
38}
39
40impl Default for EngineConfig {
41    fn default() -> Self {
42        Self {
43            scoring: ScoringWeights::default(),
44            health: HealthConfig::default(),
45            minimum_health_score: 0.2,
46            default_cooldown_seconds: 60,
47            clock: None,
48        }
49    }
50}