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