kestrel_timer/
task.rs

1use std::future::Future;
2use std::num::NonZeroUsize;
3use std::pin::Pin;
4use std::sync::Arc;
5
6use lite_sync::oneshot::lite::{Receiver, Sender, State, channel};
7use lite_sync::spsc::{self, TryRecvError};
8
9/// One-shot task completion state constants
10///
11/// 一次性任务完成状态常量
12const ONESHOT_PENDING: u8 = 0;
13const ONESHOT_CALLED: u8 = 1;
14const ONESHOT_CANCELLED: u8 = 2;
15
16/// Task Completion Reason for Periodic Tasks
17///
18/// Indicates the reason for task completion, called or cancelled.
19///
20/// 任务完成原因,调用或取消。
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum TaskCompletion {
23    /// Task was called
24    ///
25    /// 任务被调用
26    Called,
27    /// Task was cancelled
28    ///
29    /// 任务被取消
30    Cancelled,
31}
32
33impl State for TaskCompletion {
34    #[inline]
35    fn to_u8(&self) -> u8 {
36        match self {
37            TaskCompletion::Called => ONESHOT_CALLED,
38            TaskCompletion::Cancelled => ONESHOT_CANCELLED,
39        }
40    }
41
42    #[inline]
43    fn from_u8(value: u8) -> Option<Self> {
44        match value {
45            ONESHOT_CALLED => Some(TaskCompletion::Called),
46            ONESHOT_CANCELLED => Some(TaskCompletion::Cancelled),
47            _ => None,
48        }
49    }
50
51    #[inline]
52    fn pending_value() -> u8 {
53        ONESHOT_PENDING
54    }
55}
56
57/// Unique identifier for timer tasks
58///
59/// Now wraps a DeferredMap key (u64) which includes generation information
60/// for safe reference and prevention of use-after-free.
61///
62/// 定时器任务唯一标识符
63///
64/// 现在封装 DeferredMap key (u64),包含代数信息以实现安全引用和防止释放后使用
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
66pub struct TaskId(u64);
67
68impl TaskId {
69    /// Create TaskId from DeferredMap key (internal use)
70    ///
71    /// 从 DeferredMap key 创建 TaskId (内部使用)
72    #[inline]
73    pub(crate) fn from_key(key: u64) -> Self {
74        TaskId(key)
75    }
76
77    /// Get the DeferredMap key
78    ///
79    /// 获取 DeferredMap key
80    #[inline]
81    pub(crate) fn key(&self) -> u64 {
82        self.0
83    }
84
85    /// Get the numeric value of the task ID
86    ///
87    /// 获取任务 ID 的数值
88    #[inline]
89    pub fn as_u64(&self) -> u64 {
90        self.0
91    }
92}
93
94pub struct TaskHandle {
95    handle: deferred_map::Handle,
96}
97
98impl TaskHandle {
99    /// Create a new task handle
100    ///
101    /// 创建一个新的任务句柄
102    #[inline]
103    pub(crate) fn new(handle: deferred_map::Handle) -> Self {
104        Self { handle }
105    }
106
107    /// Get the task ID
108    ///
109    /// 获取任务 ID
110    #[inline]
111    pub fn task_id(&self) -> TaskId {
112        TaskId::from_key(self.handle.key())
113    }
114
115    /// Convert to deferred map handle
116    ///
117    /// 转换为 deferred map 句柄
118    #[inline]
119    pub(crate) fn into_handle(self) -> deferred_map::Handle {
120        self.handle
121    }
122}
123
124/// Timer Callback Trait
125///
126/// Types implementing this trait can be used as timer callbacks.
127///
128/// 可实现此特性的类型可以作为定时器回调函数。
129///
130/// # Examples (示例)
131///
132/// ```
133/// use kestrel_timer::task::TimerCallback;
134/// use std::future::Future;
135/// use std::pin::Pin;
136///
137/// struct MyCallback;
138///
139/// impl TimerCallback for MyCallback {
140///     fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
141///         Box::pin(async {
142///             println!("Timer callback executed!");
143///         })
144///     }
145/// }
146/// ```
147pub trait TimerCallback: Send + Sync + 'static {
148    /// Execute callback, returns a Future
149    ///
150    /// 执行回调函数,返回一个 Future
151    fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>>;
152}
153
154/// Implement TimerCallback trait for closures
155///
156/// Supports Fn() -> Future closures, can be called multiple times, suitable for periodic tasks
157///
158/// 实现 TimerCallback 特性的类型,支持 Fn() -> Future 闭包,可以多次调用,适合周期性任务
159impl<F, Fut> TimerCallback for F
160where
161    F: Fn() -> Fut + Send + Sync + 'static,
162    Fut: Future<Output = ()> + Send + 'static,
163{
164    fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
165        Box::pin(self())
166    }
167}
168
169/// Callback wrapper for standardized callback creation and management
170///
171/// Callback 包装器,用于标准化回调创建和管理
172///
173/// # Examples (示例)
174///
175/// ```
176/// use kestrel_timer::CallbackWrapper;
177///
178/// let callback = CallbackWrapper::new(|| async {
179///     println!("Timer callback executed!");
180/// });
181/// ```
182#[derive(Clone)]
183pub struct CallbackWrapper {
184    callback: Arc<dyn TimerCallback>,
185}
186
187impl CallbackWrapper {
188    /// Create a new callback wrapper
189    ///
190    /// # Parameters
191    /// - `callback`: Callback object implementing TimerCallback trait
192    ///
193    /// # 创建一个新的回调包装器
194    ///
195    /// # 参数
196    /// - `callback`: 实现 TimerCallback 特性的回调对象
197    ///
198    /// # Examples (示例)
199    ///
200    /// ```
201    /// use kestrel_timer::CallbackWrapper;
202    ///
203    /// let callback = CallbackWrapper::new(|| async {
204    ///     println!("Timer fired!"); // 定时器触发
205    /// });
206    /// ```
207    #[inline]
208    pub fn new(callback: impl TimerCallback) -> Self {
209        Self {
210            callback: Arc::new(callback),
211        }
212    }
213
214    /// Call the callback function
215    ///
216    /// 调用回调函数
217    #[inline]
218    pub(crate) fn call(&self) -> Pin<Box<dyn Future<Output = ()> + Send>> {
219        self.callback.call()
220    }
221}
222
223/// Task type enum to distinguish between one-shot and periodic timers
224///
225/// 任务类型枚举,用于区分一次性和周期性定时器
226#[derive(Clone)]
227pub enum TaskType {
228    /// One-shot timer: executes once and completes
229    ///
230    /// 一次性定时器:执行一次后完成
231    OneShot,
232
233    /// Periodic timer: repeats at fixed intervals
234    ///
235    /// 周期性定时器:按固定间隔重复执行
236    Periodic {
237        /// Period interval for periodic tasks
238        ///
239        /// 周期任务的间隔时间
240        interval: std::time::Duration,
241        /// Buffer size for periodic task completion notifier
242        ///
243        /// 周期性任务完成通知器的缓冲区大小
244        buffer_size: NonZeroUsize,
245    },
246}
247
248/// Task type enum to distinguish between one-shot and periodic timers
249///
250/// 任务类型枚举,用于区分一次性和周期性定时器
251pub enum TaskTypeWithCompletionNotifier {
252    /// One-shot timer: executes once and completes
253    ///
254    /// 一次性定时器:执行一次后完成
255    OneShot {
256        completion_notifier: Sender<TaskCompletion>,
257    },
258
259    /// Periodic timer: repeats at fixed intervals
260    ///
261    /// 周期性定时器:按固定间隔重复执行
262    Periodic {
263        /// Period interval for periodic tasks
264        ///
265        /// 周期任务的间隔时间
266        interval: std::time::Duration,
267        /// Completion notifier for periodic tasks
268        ///
269        /// 周期性任务完成通知器
270        completion_notifier: PeriodicCompletionNotifier,
271    },
272}
273
274impl TaskTypeWithCompletionNotifier {
275    /// Get the interval for periodic tasks
276    ///
277    /// Returns `None` for one-shot tasks
278    ///
279    /// 获取周期任务的间隔时间
280    ///
281    /// 对于一次性任务返回 `None`
282    #[inline]
283    pub fn get_interval(&self) -> Option<std::time::Duration> {
284        match self {
285            TaskTypeWithCompletionNotifier::Periodic { interval, .. } => Some(*interval),
286            TaskTypeWithCompletionNotifier::OneShot { .. } => None,
287        }
288    }
289}
290
291/// Completion notifier for periodic tasks
292///
293/// Uses custom SPSC channel for high-performance, low-latency notification
294///
295/// 周期任务完成通知器
296///
297/// 使用自定义 SPSC 通道实现高性能、低延迟的通知
298pub struct PeriodicCompletionNotifier(pub spsc::Sender<TaskCompletion, 32>);
299
300/// Completion receiver for periodic tasks
301///
302/// 周期任务完成通知接收器
303pub struct PeriodicCompletionReceiver(pub spsc::Receiver<TaskCompletion, 32>);
304
305impl PeriodicCompletionReceiver {
306    /// Try to receive a completion notification
307    ///
308    /// 尝试接收完成通知
309    #[inline]
310    pub fn try_recv(&mut self) -> Result<TaskCompletion, TryRecvError> {
311        self.0.try_recv()
312    }
313
314    /// Receive a completion notification
315    ///
316    /// 接收完成通知
317    #[inline]
318    pub async fn recv(&mut self) -> Option<TaskCompletion> {
319        self.0.recv().await
320    }
321}
322
323/// Completion notifier for one-shot tasks
324///
325/// 一次性任务完成通知器
326pub enum CompletionNotifier {
327    OneShot(Sender<TaskCompletion>),
328    Periodic(PeriodicCompletionNotifier),
329}
330
331/// Completion receiver for one-shot and periodic tasks
332///
333/// 一次性和周期任务完成通知接收器
334pub enum CompletionReceiver {
335    OneShot(Receiver<TaskCompletion>),
336    Periodic(PeriodicCompletionReceiver),
337}
338
339/// Timer Task
340///
341/// Users interact via a two-step API
342/// 1. Create task using `TimerTask::new_oneshot()` or `TimerTask::new_periodic()`
343/// 2. Register task using `TimerWheel::register()` or `TimerService::register()`
344///
345/// TaskId is assigned when the task is inserted into the timing wheel.
346///
347/// 定时器任务
348///
349/// 用户通过两步 API 与定时器交互
350/// 1. 使用 `TimerTask::new_oneshot()` 或 `TimerTask::new_periodic()` 创建任务
351/// 2. 使用 `TimerWheel::register()` 或 `TimerService::register()` 注册任务
352///
353/// TaskId 在任务插入到时间轮时分配
354pub struct TimerTask {
355    /// Task type (one-shot or periodic)
356    ///
357    /// 任务类型(一次性或周期性)
358    pub(crate) task_type: TaskType,
359
360    /// User-specified delay duration (initial delay for periodic tasks)
361    ///
362    /// 用户指定的延迟时间(周期任务的初始延迟)
363    pub(crate) delay: std::time::Duration,
364
365    /// Async callback function, optional
366    ///
367    /// 异步回调函数,可选
368    pub(crate) callback: Option<CallbackWrapper>,
369}
370
371impl TimerTask {
372    /// Create a new one-shot timer task
373    ///
374    /// # Parameters
375    /// - `delay`: Delay duration before task execution
376    /// - `callback`: Callback function, optional
377    ///
378    /// # Note
379    /// TaskId will be assigned when the task is inserted into the timing wheel.
380    ///
381    /// 创建一个新的一次性定时器任务
382    ///
383    /// # 参数
384    /// - `delay`: 任务执行前的延迟时间
385    /// - `callback`: 回调函数,可选
386    ///
387    /// # 注意
388    /// TaskId 将在任务插入到时间轮时分配
389    #[inline]
390    pub fn new_oneshot(delay: std::time::Duration, callback: Option<CallbackWrapper>) -> Self {
391        Self {
392            task_type: TaskType::OneShot,
393            delay,
394            callback,
395        }
396    }
397
398    /// Create a new periodic timer task
399    ///
400    /// # Parameters
401    /// - `initial_delay`: Initial delay before first execution
402    /// - `interval`: Interval between subsequent executions
403    /// - `callback`: Callback function, optional
404    ///
405    /// # Note
406    /// TaskId will be assigned when the task is inserted into the timing wheel.
407    ///
408    /// 创建一个新的周期性定时器任务
409    ///
410    /// # 参数
411    /// - `initial_delay`: 首次执行前的初始延迟
412    /// - `interval`: 后续执行之间的间隔
413    /// - `callback`: 回调函数,可选
414    ///
415    /// # 注意
416    /// TaskId 将在任务插入到时间轮时分配
417    #[inline]
418    pub fn new_periodic(
419        initial_delay: std::time::Duration,
420        interval: std::time::Duration,
421        callback: Option<CallbackWrapper>,
422        buffer_size: Option<NonZeroUsize>,
423    ) -> Self {
424        Self {
425            task_type: TaskType::Periodic {
426                interval,
427                buffer_size: buffer_size.unwrap_or(NonZeroUsize::new(32).unwrap()),
428            },
429            delay: initial_delay,
430            callback,
431        }
432    }
433
434    /// Get task type
435    ///
436    /// 获取任务类型
437    #[inline]
438    pub fn get_task_type(&self) -> &TaskType {
439        &self.task_type
440    }
441
442    /// Get the interval for periodic tasks
443    ///
444    /// Returns `None` for one-shot tasks
445    ///
446    /// 获取周期任务的间隔时间
447    ///
448    /// 对于一次性任务返回 `None`
449    #[inline]
450    pub fn get_interval(&self) -> Option<std::time::Duration> {
451        match self.task_type {
452            TaskType::Periodic { interval, .. } => Some(interval),
453            TaskType::OneShot => None,
454        }
455    }
456}
457
458/// Timer Task
459///
460/// Users interact via a two-step API
461/// 1. Create task using `TimerTask::new_oneshot()` or `TimerTask::new_periodic()`
462/// 2. Register task using `TimerWheel::register()` or `TimerService::register()`
463///
464/// 定时器任务
465///
466/// 用户通过两步 API 与定时器交互
467/// 1. 使用 `TimerTask::new_oneshot()` 或 `TimerTask::new_periodic()` 创建任务
468/// 2. 使用 `TimerWheel::register()` 或 `TimerService::register()` 注册任务
469pub struct TimerTaskWithCompletionNotifier {
470    /// Task type (one-shot or periodic)
471    ///
472    /// 任务类型(一次性或周期性)
473    pub(crate) task_type: TaskTypeWithCompletionNotifier,
474
475    /// User-specified delay duration (initial delay for periodic tasks)
476    ///
477    /// 用户指定的延迟时间(周期任务的初始延迟)
478    pub(crate) delay: std::time::Duration,
479
480    /// Async callback function, optional
481    ///
482    /// 异步回调函数,可选
483    pub(crate) callback: Option<CallbackWrapper>,
484}
485
486impl TimerTaskWithCompletionNotifier {
487    /// Create a new timer task with completion notifier from a timer task
488    ///
489    /// TaskId will be assigned later when inserted into the timing wheel
490    ///
491    /// 从定时器任务创建一个新的定时器任务完成通知器
492    ///
493    /// TaskId 将在插入到时间轮时分配
494    ///
495    /// # Parameters
496    /// - `task`: The timer task to create from
497    ///
498    /// # Returns
499    /// A tuple containing the new timer task with completion notifier and the completion receiver
500    ///
501    /// 返回一个包含新的定时器任务完成通知器和完成通知接收器的元组
502    ///
503    pub fn from_timer_task(task: TimerTask) -> (Self, CompletionReceiver) {
504        match task.task_type {
505            TaskType::OneShot => {
506                // Create oneshot notifier and receiver with optimized single Arc allocation
507                // 创建 oneshot 通知器和接收器,使用优化的单个 Arc 分配
508                let (notifier, receiver) = channel();
509
510                (
511                    Self {
512                        task_type: TaskTypeWithCompletionNotifier::OneShot {
513                            completion_notifier: notifier,
514                        },
515                        delay: task.delay,
516                        callback: task.callback,
517                    },
518                    CompletionReceiver::OneShot(receiver),
519                )
520            }
521            TaskType::Periodic {
522                interval,
523                buffer_size,
524            } => {
525                // Use custom SPSC channel for high-performance periodic notification
526                // 使用自定义 SPSC 通道实现高性能周期通知
527                let (tx, rx) = spsc::channel(buffer_size);
528
529                let notifier = PeriodicCompletionNotifier(tx);
530                let receiver = PeriodicCompletionReceiver(rx);
531
532                (
533                    Self {
534                        task_type: TaskTypeWithCompletionNotifier::Periodic {
535                            interval,
536                            completion_notifier: notifier,
537                        },
538                        delay: task.delay,
539                        callback: task.callback,
540                    },
541                    CompletionReceiver::Periodic(receiver),
542                )
543            }
544        }
545    }
546
547    /// Into task type
548    ///
549    /// 将任务类型转换为完成通知器
550    #[inline]
551    pub fn into_task_type(self) -> TaskTypeWithCompletionNotifier {
552        self.task_type
553    }
554
555    /// Get the interval for periodic tasks
556    ///
557    /// Returns `None` for one-shot tasks
558    ///
559    /// 获取周期任务的间隔时间
560    ///
561    /// 对于一次性任务返回 `None`
562    #[inline]
563    pub fn get_interval(&self) -> Option<std::time::Duration> {
564        self.task_type.get_interval()
565    }
566}
567
568pub(crate) struct TimerTaskForWheel {
569    pub(crate) task_id: TaskId,
570    pub(crate) task: TimerTaskWithCompletionNotifier,
571    pub(crate) deadline_tick: u64,
572    pub(crate) rounds: u32,
573}
574
575impl TimerTaskForWheel {
576    /// Create a new timer task for wheel with assigned TaskId
577    ///
578    /// 使用分配的 TaskId 创建一个新的定时器任务用于时间轮
579    ///
580    /// # Parameters
581    /// - `task_id`: The TaskId assigned by DeferredMap
582    /// - `task`: The timer task to create from
583    /// - `deadline_tick`: The deadline tick for the task
584    /// - `rounds`: The rounds for the task
585    ///
586    /// # Returns
587    /// A new timer task for wheel
588    ///
589    /// 返回一个新的定时器任务用于时间轮
590    ///
591    #[inline]
592    pub(crate) fn new_with_id(
593        task_id: TaskId,
594        task: TimerTaskWithCompletionNotifier,
595        deadline_tick: u64,
596        rounds: u32,
597    ) -> Self {
598        Self {
599            task_id,
600            task,
601            deadline_tick,
602            rounds,
603        }
604    }
605
606    /// Get task ID
607    ///
608    /// 获取任务 ID
609    #[inline]
610    pub fn get_id(&self) -> TaskId {
611        self.task_id
612    }
613
614    /// Into task type
615    ///
616    /// 将任务类型转换为完成通知器
617    #[inline]
618    pub fn into_task_type(self) -> TaskTypeWithCompletionNotifier {
619        self.task.into_task_type()
620    }
621
622    /// Update the delay of the timer task
623    ///
624    /// 更新定时器任务的延迟
625    ///
626    /// # Parameters
627    /// - `delay`: The new delay for the task
628    ///
629    #[inline]
630    pub fn update_delay(&mut self, delay: std::time::Duration) {
631        self.task.delay = delay
632    }
633
634    /// Update the callback of the timer task
635    ///
636    /// 更新定时器任务的回调
637    ///
638    /// # Parameters
639    /// - `callback`: The new callback for the task
640    ///
641    #[inline]
642    pub fn update_callback(&mut self, callback: CallbackWrapper) {
643        self.task.callback = Some(callback)
644    }
645}
646
647/// Task location information (including level) for hierarchical timing wheel
648///
649/// Memory layout optimization: level field placed first to reduce padding via struct alignment
650///
651/// 任务位置信息(包括层级)用于分层时间轮
652///
653/// 内存布局优化:将 level 字段放在第一位,通过结构体对齐来减少填充
654#[derive(Debug, Clone, Copy)]
655pub(crate) struct TaskLocation {
656    /// Slot index
657    ///
658    /// 槽索引
659    pub slot_index: usize,
660    /// Index position of task in slot Vec for O(1) cancellation
661    ///
662    /// 槽向量中任务的索引位置,用于 O(1) 取消
663    pub vec_index: usize,
664    /// Level: 0 = L0 (bottom layer), 1 = L1 (upper layer)
665    /// Using u8 instead of bool to reserve space for potential multi-layer expansion
666    ///
667    /// 层级:0 = L0(底层),1 = L1(上层)
668    /// 使用 u8 而不是 bool 来保留空间,用于潜在的多层扩展
669    pub level: u8,
670}
671
672impl TaskLocation {
673    /// Create a new task location information
674    ///
675    /// 创建一个新的任务位置信息
676    #[inline(always)]
677    pub fn new(level: u8, slot_index: usize, vec_index: usize) -> Self {
678        Self {
679            slot_index,
680            vec_index,
681            level,
682        }
683    }
684}