Skip to main content

syncor_core/watch/
poller.rs

1use std::time::Duration;
2use tokio::sync::mpsc;
3use tokio::task::JoinHandle;
4
5pub struct PollEvent;
6
7pub struct Poller {
8    handle: JoinHandle<()>,
9    cancel: tokio::sync::watch::Sender<bool>,
10}
11
12impl Poller {
13    pub fn start(interval: Duration, tx: mpsc::Sender<PollEvent>) -> Self {
14        let (cancel_tx, mut cancel_rx) = tokio::sync::watch::channel(false);
15
16        let handle = tokio::spawn(async move {
17            let mut ticker = tokio::time::interval(interval);
18            // consume the immediate first tick so interval starts fresh
19            ticker.tick().await;
20
21            loop {
22                tokio::select! {
23                    _ = ticker.tick() => {
24                        if tx.send(PollEvent).await.is_err() {
25                            break;
26                        }
27                    }
28                    _ = cancel_rx.changed() => {
29                        if *cancel_rx.borrow() {
30                            break;
31                        }
32                    }
33                }
34            }
35        });
36
37        Self {
38            handle,
39            cancel: cancel_tx,
40        }
41    }
42
43    pub fn stop(self) {
44        let _ = self.cancel.send(true);
45        self.handle.abort();
46    }
47}