kestrel_protocol_timer/
task.rs1use std::future::Future;
2use std::pin::Pin;
3use std::sync::atomic::{AtomicU64, Ordering};
4use std::sync::Arc;
5use tokio::sync::oneshot;
6
7static NEXT_TASK_ID: AtomicU64 = AtomicU64::new(1);
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub struct TaskId(u64);
13
14impl TaskId {
15 pub fn new() -> Self {
17 TaskId(NEXT_TASK_ID.fetch_add(1, Ordering::Relaxed))
18 }
19
20 pub fn as_u64(&self) -> u64 {
22 self.0
23 }
24}
25
26impl Default for TaskId {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32pub trait TimerCallback: Send + Sync + 'static {
54 fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>>;
56}
57
58impl<F, Fut> TimerCallback for F
61where
62 F: Fn() -> Fut + Send + Sync + 'static,
63 Fut: Future<Output = ()> + Send + 'static,
64{
65 fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
66 Box::pin(self())
67 }
68}
69
70pub type CallbackWrapper = Arc<dyn TimerCallback>;
72
73pub struct CompletionNotifier(pub oneshot::Sender<()>);
75
76pub struct TimerTask {
78 pub id: TaskId,
80
81 pub deadline_tick: u64,
83
84 pub rounds: u32,
86
87 pub callback: Option<CallbackWrapper>,
89
90 pub completion_notifier: CompletionNotifier,
92}
93
94impl TimerTask {
95 pub fn once(
97 deadline_tick: u64,
98 rounds: u32,
99 callback: Option<CallbackWrapper>,
100 completion_notifier: CompletionNotifier,
101 ) -> Self {
102 Self {
103 id: TaskId::new(),
104 deadline_tick,
105 rounds,
106 callback,
107 completion_notifier,
108 }
109 }
110
111 pub fn get_callback(&self) -> Option<CallbackWrapper> {
113 self.callback.as_ref().map(Arc::clone)
114 }
115}
116
117#[derive(Debug, Clone)]
119pub struct TaskLocation {
120 pub slot_index: usize,
121 pub vec_index: usize,
123 #[allow(dead_code)]
124 pub task_id: TaskId,
125}
126
127impl TaskLocation {
128 pub fn new(slot_index: usize, vec_index: usize, task_id: TaskId) -> Self {
129 Self {
130 slot_index,
131 vec_index,
132 task_id,
133 }
134 }
135}
136