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 Wakeup,
11
12 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 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
48impl 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}