kestrel_timer/task.rs
1use std::future::Future;
2use std::pin::Pin;
3use std::sync::atomic::{AtomicU64, Ordering};
4use std::sync::Arc;
5use tokio::sync::oneshot;
6
7/// Global unique task ID generator
8///
9/// 全局唯一任务 ID 生成器
10static NEXT_TASK_ID: AtomicU64 = AtomicU64::new(1);
11
12/// Task Completion Reason
13///
14/// Indicates the reason for task completion, either expired or cancelled.
15///
16/// 任务完成原因,要么是过期,要么是取消。
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum TaskCompletionReason {
19 /// Task expired normally
20 ///
21 /// 任务正常过期
22 Expired,
23 /// Task was cancelled
24 ///
25 /// 任务被取消
26 Cancelled,
27}
28
29/// Unique identifier for timer tasks
30///
31/// 定时器任务唯一标识符
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub struct TaskId(u64);
34
35impl TaskId {
36 /// Generate a new unique task ID (internal use)
37 ///
38 /// 生成一个新的唯一任务 ID (内部使用)
39 #[inline]
40 pub(crate) fn new() -> Self {
41 TaskId(NEXT_TASK_ID.fetch_add(1, Ordering::Relaxed))
42 }
43
44 /// Get the numeric value of the task ID
45 ///
46 /// 获取任务 ID 的数值
47 #[inline]
48 pub fn as_u64(&self) -> u64 {
49 self.0
50 }
51}
52
53impl Default for TaskId {
54 #[inline]
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60/// Timer Callback Trait
61///
62/// Types implementing this trait can be used as timer callbacks.
63///
64/// 可实现此特性的类型可以作为定时器回调函数。
65///
66/// # Examples (示例)
67///
68/// ```
69/// use kestrel_timer::task::TimerCallback;
70/// use std::future::Future;
71/// use std::pin::Pin;
72///
73/// struct MyCallback;
74///
75/// impl TimerCallback for MyCallback {
76/// fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
77/// Box::pin(async {
78/// println!("Timer callback executed!");
79/// })
80/// }
81/// }
82/// ```
83pub trait TimerCallback: Send + Sync + 'static {
84 /// Execute callback, returns a Future
85 ///
86 /// 执行回调函数,返回一个 Future
87 fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>>;
88}
89
90/// Implement TimerCallback trait for closures
91///
92/// Supports Fn() -> Future closures, can be called multiple times, suitable for periodic tasks
93///
94/// 实现 TimerCallback 特性的类型,支持 Fn() -> Future 闭包,可以多次调用,适合周期性任务
95impl<F, Fut> TimerCallback for F
96where
97 F: Fn() -> Fut + Send + Sync + 'static,
98 Fut: Future<Output = ()> + Send + 'static,
99{
100 fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
101 Box::pin(self())
102 }
103}
104
105/// Callback wrapper for standardized callback creation and management
106///
107/// Callback 包装器,用于标准化回调创建和管理
108///
109/// # Examples (示例)
110///
111/// ```
112/// use kestrel_timer::CallbackWrapper;
113///
114/// let callback = CallbackWrapper::new(|| async {
115/// println!("Timer callback executed!");
116/// });
117/// ```
118#[derive(Clone)]
119pub struct CallbackWrapper {
120 callback: Arc<dyn TimerCallback>,
121}
122
123impl CallbackWrapper {
124 /// Create a new callback wrapper
125 ///
126 /// # Parameters
127 /// - `callback`: Callback object implementing TimerCallback trait
128 ///
129 /// # 创建一个新的回调包装器
130 ///
131 /// # 参数
132 /// - `callback`: 实现 TimerCallback 特性的回调对象
133 ///
134 /// # Examples (示例)
135 ///
136 /// ```
137 /// use kestrel_timer::CallbackWrapper;
138 ///
139 /// let callback = CallbackWrapper::new(|| async {
140 /// println!("Timer fired!"); // 定时器触发
141 /// });
142 /// ```
143 #[inline]
144 pub fn new(callback: impl TimerCallback) -> Self {
145 Self {
146 callback: Arc::new(callback),
147 }
148 }
149
150 /// Call the callback function
151 ///
152 /// 调用回调函数
153 #[inline]
154 pub(crate) fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
155 self.callback.call()
156 }
157}
158
159/// Completion notifier for sending notifications when tasks complete
160///
161/// 完成通知器,用于发送任务完成通知
162pub struct CompletionNotifier(pub oneshot::Sender<TaskCompletionReason>);
163
164/// Timer Task
165///
166/// Users interact via a two-step API
167/// 1. Create task using `TimerTask::new()`
168/// 2. Register task using `TimerWheel::register()` or `TimerService::register()`
169///
170/// 定时器任务
171///
172/// 用户通过两步 API 与定时器交互
173/// 1. 使用 `TimerTask::new()` 创建任务
174/// 2. 使用 `TimerWheel::register()` 或 `TimerService::register()` 注册任务
175pub struct TimerTask {
176 /// Unique task identifier
177 ///
178 /// 唯一任务标识符
179 pub(crate) id: TaskId,
180
181 /// User-specified delay duration
182 ///
183 /// 用户指定的延迟时间
184 pub(crate) delay: std::time::Duration,
185
186 /// Expiration time in ticks relative to the timing wheel
187 ///
188 /// 相对于时间轮的过期时间(以 tick 为单位)
189 pub(crate) deadline_tick: u64,
190
191 /// Round counter for tasks beyond the wheel's range
192 ///
193 /// 超出时间轮范围的任务轮数计数器
194 pub(crate) rounds: u32,
195
196 /// Async callback function, optional
197 ///
198 /// 异步回调函数,可选
199 pub(crate) callback: Option<CallbackWrapper>,
200
201 /// Completion notifier for sending notifications when task completes, created during registration
202 ///
203 /// 完成通知器,用于发送任务完成通知,在注册期间创建
204 pub(crate) completion_notifier: Option<CompletionNotifier>,
205}
206
207impl TimerTask {
208 /// Create a new timer task, internal use
209 ///
210 /// # Parameters
211 /// - `delay`: Delay duration
212 /// - `callback`: Callback function, optional
213 ///
214 /// # Note
215 /// This is an internal method, users should use `TimerWheel::create_task()` or `TimerService::create_task()` to create tasks.
216 ///
217 ///
218 /// 创建一个新的定时器任务,内部使用
219 ///
220 /// # 参数
221 /// - `delay`: 延迟时间
222 /// - `callback`: 回调函数,可选
223 ///
224 /// # 注意
225 /// 这是一个内部方法,用户应该使用 `TimerWheel::create_task()` 或 `TimerService::create_task()` 来创建任务。
226 #[inline]
227 pub(crate) fn new(delay: std::time::Duration, callback: Option<CallbackWrapper>) -> Self {
228 Self {
229 id: TaskId::new(),
230 delay,
231 deadline_tick: 0,
232 rounds: 0,
233 callback,
234 completion_notifier: None,
235 }
236 }
237
238 /// Get task ID
239 ///
240 /// 获取任务 ID
241 ///
242 /// # Examples (示例)
243 ///
244 /// ```no_run
245 /// use kestrel_timer::TimerWheel;
246 /// use std::time::Duration;
247 ///
248 /// let task = TimerWheel::create_task(Duration::from_secs(1), None);
249 /// let task_id = task.get_id();
250 /// println!("Task ID: {:?}", task_id);
251 /// ```
252 pub fn get_id(&self) -> TaskId {
253 self.id
254 }
255
256 /// Prepare for registration (called by timing wheel during registration)
257 ///
258 /// 准备注册(在注册期间由时间轮调用)
259 #[allow(dead_code)]
260 pub(crate) fn prepare_for_registration(
261 &mut self,
262 completion_notifier: CompletionNotifier,
263 deadline_tick: u64,
264 rounds: u32,
265 ) {
266 self.completion_notifier = Some(completion_notifier);
267 self.deadline_tick = deadline_tick;
268 self.rounds = rounds;
269 }
270
271 /// Get a clone of the callback function if present
272 ///
273 /// 获取回调函数(如果存在)
274 #[inline]
275 pub(crate) fn get_callback(&self) -> Option<CallbackWrapper> {
276 self.callback.clone()
277 }
278}
279
280/// Task location information (including level) for hierarchical timing wheel
281///
282/// Memory layout optimization: level field placed first to reduce padding via struct alignment
283///
284/// 任务位置信息(包括层级)用于分层时间轮
285///
286/// 内存布局优化:将 level 字段放在第一位,通过结构体对齐来减少填充
287#[derive(Debug, Clone, Copy)]
288pub(crate) struct TaskLocation {
289 /// Slot index
290 ///
291 /// 槽索引
292 pub slot_index: usize,
293 /// Index position of task in slot Vec for O(1) cancellation
294 ///
295 /// 槽向量中任务的索引位置,用于 O(1) 取消
296 pub vec_index: usize,
297 /// Level: 0 = L0 (bottom layer), 1 = L1 (upper layer)
298 /// Using u8 instead of bool to reserve space for potential multi-layer expansion
299 ///
300 /// 层级:0 = L0(底层),1 = L1(上层)
301 /// 使用 u8 而不是 bool 来保留空间,用于潜在的多层扩展
302 pub level: u8,
303}
304
305impl TaskLocation {
306 /// Create a new task location information
307 ///
308 /// 创建一个新的任务位置信息
309 #[inline(always)]
310 pub fn new(level: u8, slot_index: usize, vec_index: usize) -> Self {
311 Self {
312 slot_index,
313 vec_index,
314 level,
315 }
316 }
317}
318