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)]
14pub enum TaskCompletionReason {
15 Expired,
17 Cancelled,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub struct TaskId(u64);
24
25impl TaskId {
26 #[inline]
28 pub(crate) fn new() -> Self {
29 TaskId(NEXT_TASK_ID.fetch_add(1, Ordering::Relaxed))
30 }
31
32 #[inline]
34 pub fn as_u64(&self) -> u64 {
35 self.0
36 }
37}
38
39impl Default for TaskId {
40 #[inline]
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46pub trait TimerCallback: Send + Sync + 'static {
68 fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>>;
70}
71
72impl<F, Fut> TimerCallback for F
75where
76 F: Fn() -> Fut + Send + Sync + 'static,
77 Fut: Future<Output = ()> + Send + 'static,
78{
79 fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
80 Box::pin(self())
81 }
82}
83
84#[derive(Clone)]
96pub struct CallbackWrapper {
97 callback: Arc<dyn TimerCallback>,
98}
99
100impl CallbackWrapper {
101 #[inline]
116 pub fn new(callback: impl TimerCallback) -> Self {
117 Self {
118 callback: Arc::new(callback),
119 }
120 }
121
122 #[inline]
124 pub(crate) fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
125 self.callback.call()
126 }
127}
128
129pub struct CompletionNotifier(pub oneshot::Sender<TaskCompletionReason>);
131
132pub struct TimerTask {
138 pub(crate) id: TaskId,
140
141 pub(crate) delay: std::time::Duration,
143
144 pub(crate) deadline_tick: u64,
146
147 pub(crate) rounds: u32,
149
150 pub(crate) callback: Option<CallbackWrapper>,
152
153 pub(crate) completion_notifier: Option<CompletionNotifier>,
155}
156
157impl TimerTask {
158 pub(crate) fn new(delay: std::time::Duration, callback: Option<CallbackWrapper>) -> Self {
167 Self {
168 id: TaskId::new(),
169 delay,
170 deadline_tick: 0,
171 rounds: 0,
172 callback,
173 completion_notifier: None,
174 }
175 }
176
177 pub fn get_id(&self) -> TaskId {
189 self.id
190 }
191
192 pub(crate) fn prepare_for_registration(
194 &mut self,
195 completion_notifier: CompletionNotifier,
196 deadline_tick: u64,
197 rounds: u32,
198 ) {
199 self.completion_notifier = Some(completion_notifier);
200 self.deadline_tick = deadline_tick;
201 self.rounds = rounds;
202 }
203
204 #[inline]
206 pub(crate) fn get_callback(&self) -> Option<CallbackWrapper> {
207 self.callback.clone()
208 }
209}
210
211#[derive(Debug, Clone)]
213pub struct TaskLocation {
214 pub slot_index: usize,
215 pub vec_index: usize,
217 #[allow(dead_code)]
218 pub task_id: TaskId,
219}
220
221impl TaskLocation {
222 pub fn new(slot_index: usize, vec_index: usize, task_id: TaskId) -> Self {
223 Self {
224 slot_index,
225 vec_index,
226 task_id,
227 }
228 }
229}
230