use crate::drift::action::DriftAction;
use crate::drift::detector::DriftLevel;
pub trait DriftStrategy {
fn decide(&self, level: DriftLevel, samples_seen: u64) -> DriftAction;
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StaticStrategy {
pub warning_action: DriftAction,
pub drift_action: DriftAction,
}
impl StaticStrategy {
pub const fn new(warning_action: DriftAction, drift_action: DriftAction) -> Self {
Self {
warning_action,
drift_action,
}
}
}
impl Default for StaticStrategy {
fn default() -> Self {
Self {
warning_action: DriftAction::NotifyOnly,
drift_action: DriftAction::NotifyOnly,
}
}
}
impl DriftStrategy for StaticStrategy {
fn decide(&self, level: DriftLevel, _samples_seen: u64) -> DriftAction {
match level {
DriftLevel::None => DriftAction::NotifyOnly,
DriftLevel::Warning => self.warning_action,
DriftLevel::Drift => self.drift_action,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_strategy_is_notify_only() {
let s = StaticStrategy::default();
assert_eq!(s.decide(DriftLevel::None, 0), DriftAction::NotifyOnly);
assert_eq!(s.decide(DriftLevel::Warning, 10), DriftAction::NotifyOnly);
assert_eq!(s.decide(DriftLevel::Drift, 100), DriftAction::NotifyOnly);
}
#[test]
fn custom_strategy() {
let s = StaticStrategy::new(DriftAction::ReduceConfidence, DriftAction::ResetModel);
assert_eq!(s.decide(DriftLevel::None, 50), DriftAction::NotifyOnly);
assert_eq!(
s.decide(DriftLevel::Warning, 50),
DriftAction::ReduceConfidence
);
assert_eq!(s.decide(DriftLevel::Drift, 50), DriftAction::ResetModel);
}
#[test]
fn samples_seen_does_not_affect_static_strategy() {
let s = StaticStrategy::new(DriftAction::NotifyOnly, DriftAction::ResetModel);
assert_eq!(
s.decide(DriftLevel::Drift, 1),
s.decide(DriftLevel::Drift, 1000)
);
}
#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
let s = StaticStrategy::new(DriftAction::ReduceConfidence, DriftAction::ResetModel);
let json = serde_json::to_string(&s).unwrap();
let restored: StaticStrategy = serde_json::from_str(&json).unwrap();
assert_eq!(restored.warning_action, DriftAction::ReduceConfidence);
assert_eq!(restored.drift_action, DriftAction::ResetModel);
}
}