guinea-core 0.18.8

guinea's core: actors, reducers, scopes and the event bus
Documentation
#[macro_export]
macro_rules! ratelimit {
    ($timeout:expr, $tracing_macro:ident ! ($($arg:tt)+)) => {
        {
            static LAST: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
            let now = std::time::SystemTime::now()
                .duration_since(std::time::UNIX_EPOCH)
                .unwrap_or_default()
                .as_secs();
            let last = LAST.load(std::sync::atomic::Ordering::Relaxed);

            if now >= last + $timeout {
                if LAST.compare_exchange(last, now, std::sync::atomic::Ordering::Relaxed, std::sync::atomic::Ordering::Relaxed).is_ok() {
                    let gap = if last == 0 { 0 } else { now - last };

                    if last > 0 && gap > $timeout {
                        $crate::__private::tracing::error!(gap_s = gap, timeout_s = $timeout, "Silence timeout exceeded");
                    }

                    $crate::__private::tracing::$tracing_macro!(timeout_s = $timeout, gap_s = gap, $($arg)+);
                }
            }
        }
    };
}