kaspa_core/task/
tick.rs

1use std::{sync::Arc, time::Duration};
2use triggered::{trigger, Listener, Trigger};
3
4use super::service::{AsyncService, AsyncServiceFuture};
5
6const TICK: &str = "tick";
7
8pub enum TickReason {
9    /// Sleep went to completion, time to wake-up
10    Wakeup,
11
12    /// Service was shutdown
13    Shutdown,
14}
15
16pub struct TickService {
17    shutdown_trigger: Trigger,
18    shutdown_listener: Listener,
19}
20
21impl TickService {
22    pub fn new() -> Self {
23        let (shutdown, monitor) = trigger();
24        Self { shutdown_trigger: shutdown, shutdown_listener: monitor }
25    }
26
27    /// Waits until `duration` has elapsed when the service is started.
28    ///
29    /// Returns immediately when the service is stopped.
30    pub async fn tick(&self, duration: Duration) -> TickReason {
31        match tokio::time::timeout(duration, self.shutdown_listener.clone()).await {
32            Ok(()) => TickReason::Shutdown,
33            Err(_) => TickReason::Wakeup,
34        }
35    }
36
37    pub fn shutdown(&self) {
38        self.shutdown_trigger.trigger();
39    }
40}
41
42impl Default for TickService {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48// service trait implementation for TickService
49impl AsyncService for TickService {
50    fn ident(self: Arc<Self>) -> &'static str {
51        TICK
52    }
53
54    fn start(self: Arc<Self>) -> AsyncServiceFuture {
55        Box::pin(async move { Ok(()) })
56    }
57
58    fn signal_exit(self: Arc<Self>) {
59        self.shutdown();
60    }
61
62    fn stop(self: Arc<Self>) -> AsyncServiceFuture {
63        Box::pin(async move { Ok(()) })
64    }
65}