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