tor_guardmgr/events.rs
1//! Code to remotely notify other crates about changes in the status of the
2//! `GuardMgr`.
3
4use std::{pin::Pin, task::Poll};
5
6use crate::skew::SkewEstimate;
7use educe::Educe;
8use futures::{Stream, StreamExt};
9use tor_basic_utils::skip_fmt;
10
11/// A stream of [`SkewEstimate`] events.
12///
13/// Note that this stream can be lossy: if multiple events trigger before you
14/// read from it, you will only get the most recent estimate.
15//
16// SEMVER NOTE: this type is re-exported from tor-circmgr.
17#[derive(Clone, Educe)]
18#[educe(Debug)]
19pub struct ClockSkewEvents {
20 /// The `postage::watch::Receiver` that we're wrapping.
21 ///
22 /// We wrap this type so that we don't expose its entire API, and so that we
23 /// can migrate to some other implementation in the future if we want.
24 #[educe(Debug(method = "skip_fmt"))]
25 pub(crate) inner: postage::watch::Receiver<Option<SkewEstimate>>,
26}
27
28impl Stream for ClockSkewEvents {
29 type Item = Option<SkewEstimate>;
30
31 fn poll_next(
32 mut self: Pin<&mut Self>,
33 cx: &mut std::task::Context<'_>,
34 ) -> Poll<Option<Self::Item>> {
35 self.inner.poll_next_unpin(cx)
36 }
37}
38impl ClockSkewEvents {
39 /// Return our best estimate of our current clock skew, based on reports from the
40 /// guards and fallbacks we have contacted.
41 pub fn get(&self) -> Option<SkewEstimate> {
42 self.inner.borrow().clone()
43 }
44}