async_liveliness_monitor/
lib.rs

1use std::sync::Arc;
2
3pub mod support;
4use support::{AtomicInstant, LivelinessMonitorFuture};
5
6/// A liveliness monitor for asynchronous runtimes.
7///
8/// Its only constructor ([`LivelinessMonitor::start()`]) returns it wrapped in an [`Arc`] with strong count 1.
9/// Should that strong count reach 0 (due to dropping all the clones you may have made of that [`Arc`], or by
10/// using [`Arc::try_unwrap()`]), the associated task spawned in your runtime will end next time upon its next
11/// scheduling.
12#[non_exhaustive]
13pub struct LivelinessMonitor {
14    /// The instant of the latest liveliness report.
15    pub latest_report: AtomicInstant,
16}
17impl LivelinessMonitor {
18    /// Starts a liveliness monitor on your asynchronous runtime (of which you must pass the `spawn` method),
19    /// returning both the handle the runtime may have returned, as well as a reference counted [`LivelinessMonitor`].
20    ///
21    /// Please refer to the examples to learn more about its usage.
22    pub fn start<T, SpawnFunction: Fn(LivelinessMonitorFuture) -> T>(
23        spawn: SpawnFunction,
24    ) -> (T, Arc<LivelinessMonitor>) {
25        let this = Arc::new(LivelinessMonitor {
26            latest_report: AtomicInstant::default(),
27        });
28        (
29            spawn(LivelinessMonitorFuture {
30                monitor: Arc::downgrade(&this),
31            }),
32            this,
33        )
34    }
35
36    /// The instant of the latest liveliness report, as an [`std::time::Instant`].
37    ///
38    /// Keep in mind its resolution is limited to that of [`crate::support::AtomicDuration`],
39    /// and that a busy executor may provide updates at rather low frequencies.
40    ///
41    /// You can probably expect that if the report hasn't been updated in the last 5 seconds,
42    /// your executor is indeed stalled.
43    pub fn latest_report(&self) -> std::time::Instant {
44        self.latest_report
45            .load(std::sync::atomic::Ordering::Relaxed)
46    }
47}