use super::{ConnectionState, FailureReport, RetryBudgetSnapshot};
use std::{
sync::{Arc, OnceLock},
time::Duration,
};
pub trait Observer: Send + Sync + 'static {
fn on_state(&self, state: &ConnectionState);
fn on_failure(&self, report: &FailureReport);
fn on_backoff(&self, delay: Duration, budget: &RetryBudgetSnapshot);
}
#[derive(Clone, Debug)]
pub struct SouthwardObserverLabels {
pub channel_id: i32,
pub driver_kind: Arc<str>,
}
#[derive(Clone, Debug)]
pub struct NorthwardObserverLabels {
pub app_id: i32,
pub plugin_kind: Arc<str>,
}
pub trait ObserverFactory: Send + Sync + 'static {
#[inline]
fn create_southward(&self, _labels: SouthwardObserverLabels) -> Arc<dyn Observer> {
noop_observer_arc()
}
#[inline]
fn create_northward(&self, _labels: NorthwardObserverLabels) -> Arc<dyn Observer> {
noop_observer_arc()
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoopObserver;
impl Observer for NoopObserver {
#[inline]
fn on_state(&self, _state: &ConnectionState) {}
#[inline]
fn on_failure(&self, _report: &FailureReport) {}
#[inline]
fn on_backoff(&self, _delay: Duration, _budget: &RetryBudgetSnapshot) {}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoopObserverFactory;
impl ObserverFactory for NoopObserverFactory {
}
#[inline]
fn noop_observer_arc() -> Arc<dyn Observer> {
static OBS: OnceLock<Arc<dyn Observer>> = OnceLock::new();
Arc::clone(OBS.get_or_init(|| Arc::new(NoopObserver)))
}