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