1mod config;
96mod error;
97mod task;
98mod wheel;
99mod timer;
100mod service;
101
102pub use config::{
104 BatchConfig,
105 ServiceConfig, ServiceConfigBuilder,
106 TimerConfig, TimerConfigBuilder,
107 WheelConfig, WheelConfigBuilder,
108};
109pub use error::TimerError;
110pub use task::{CallbackWrapper, CompletionNotifier, TaskCompletionReason, TaskId, TimerCallback, TimerTask};
111pub use timer::{BatchHandle, BatchHandleIter, CompletionReceiver, TimerHandle, TimerWheel};
112pub use service::TimerService;
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use std::sync::atomic::{AtomicU32, Ordering};
118 use std::sync::Arc;
119 use std::time::Duration;
120
121 #[tokio::test]
122 async fn test_basic_timer() {
123 let timer = TimerWheel::with_defaults();
124 let counter = Arc::new(AtomicU32::new(0));
125 let counter_clone = Arc::clone(&counter);
126
127 let task = TimerWheel::create_task(
128 Duration::from_millis(50),
129 Some(CallbackWrapper::new(move || {
130 let counter = Arc::clone(&counter_clone);
131 async move {
132 counter.fetch_add(1, Ordering::SeqCst);
133 }
134 })),
135 );
136 timer.register(task);
137
138 tokio::time::sleep(Duration::from_millis(100)).await;
139 assert_eq!(counter.load(Ordering::SeqCst), 1);
140 }
141
142 #[tokio::test]
143 async fn test_multiple_timers() {
144 let timer = TimerWheel::with_defaults();
145 let counter = Arc::new(AtomicU32::new(0));
146
147 for i in 0..10 {
149 let counter_clone = Arc::clone(&counter);
150 let task = TimerWheel::create_task(
151 Duration::from_millis(10 * (i + 1)),
152 Some(CallbackWrapper::new(move || {
153 let counter = Arc::clone(&counter_clone);
154 async move {
155 counter.fetch_add(1, Ordering::SeqCst);
156 }
157 })),
158 );
159 timer.register(task);
160 }
161
162 tokio::time::sleep(Duration::from_millis(200)).await;
163 assert_eq!(counter.load(Ordering::SeqCst), 10);
164 }
165
166 #[tokio::test]
167 async fn test_timer_cancellation() {
168 let timer = TimerWheel::with_defaults();
169 let counter = Arc::new(AtomicU32::new(0));
170
171 let mut handles = Vec::new();
173 for _ in 0..5 {
174 let counter_clone = Arc::clone(&counter);
175 let task = TimerWheel::create_task(
176 Duration::from_millis(100),
177 Some(CallbackWrapper::new(move || {
178 let counter = Arc::clone(&counter_clone);
179 async move {
180 counter.fetch_add(1, Ordering::SeqCst);
181 }
182 })),
183 );
184 let handle = timer.register(task);
185 handles.push(handle);
186 }
187
188 for i in 0..3 {
190 let cancel_result = handles[i].cancel();
191 assert!(cancel_result);
192 }
193
194 tokio::time::sleep(Duration::from_millis(200)).await;
195 assert_eq!(counter.load(Ordering::SeqCst), 2);
197 }
198
199 #[tokio::test]
200 async fn test_completion_notification_once() {
201 let timer = TimerWheel::with_defaults();
202 let counter = Arc::new(AtomicU32::new(0));
203 let counter_clone = Arc::clone(&counter);
204
205 let task = TimerWheel::create_task(
206 Duration::from_millis(50),
207 Some(CallbackWrapper::new(move || {
208 let counter = Arc::clone(&counter_clone);
209 async move {
210 counter.fetch_add(1, Ordering::SeqCst);
211 }
212 })),
213 );
214 let handle = timer.register(task);
215
216 handle.into_completion_receiver().0.await.expect("Should receive completion notification");
218
219 tokio::time::sleep(Duration::from_millis(20)).await;
221 assert_eq!(counter.load(Ordering::SeqCst), 1);
222 }
223
224 #[tokio::test]
225 async fn test_notify_only_timer_once() {
226 let timer = TimerWheel::with_defaults();
227
228 let task = TimerTask::new(Duration::from_millis(50), None);
229 let handle = timer.register(task);
230
231 handle.into_completion_receiver().0.await.expect("Should receive completion notification");
233 }
234
235 #[tokio::test]
236 async fn test_batch_completion_notifications() {
237 let timer = TimerWheel::with_defaults();
238 let counter = Arc::new(AtomicU32::new(0));
239
240 let callbacks: Vec<(Duration, Option<CallbackWrapper>)> = (0..5)
242 .map(|i| {
243 let counter = Arc::clone(&counter);
244 let delay = Duration::from_millis(50 + i * 10);
245 let callback = CallbackWrapper::new(move || {
246 let counter = Arc::clone(&counter);
247 async move {
248 counter.fetch_add(1, Ordering::SeqCst);
249 }
250 });
251 (delay, Some(callback))
252 })
253 .collect();
254
255 let tasks = TimerWheel::create_batch_with_callbacks(callbacks);
256 let batch = timer.register_batch(tasks);
257 let receivers = batch.into_completion_receivers();
258
259 for rx in receivers {
261 rx.await.expect("Should receive completion notification");
262 }
263
264 tokio::time::sleep(Duration::from_millis(50)).await;
266
267 assert_eq!(counter.load(Ordering::SeqCst), 5);
269 }
270
271 #[tokio::test]
272 async fn test_completion_reason_expired() {
273 let timer = TimerWheel::with_defaults();
274
275 let task = TimerTask::new(Duration::from_millis(50), None);
276 let handle = timer.register(task);
277
278 let result = handle.into_completion_receiver().0.await.expect("Should receive completion notification");
280 assert_eq!(result, TaskCompletionReason::Expired);
281 }
282
283 #[tokio::test]
284 async fn test_completion_reason_cancelled() {
285 let timer = TimerWheel::with_defaults();
286
287 let task = TimerTask::new(Duration::from_secs(10), None);
288 let handle = timer.register(task);
289
290 let cancelled = handle.cancel();
292 assert!(cancelled);
293
294 let result = handle.into_completion_receiver().0.await.expect("Should receive completion notification");
296 assert_eq!(result, TaskCompletionReason::Cancelled);
297 }
298
299 #[tokio::test]
300 async fn test_batch_completion_reasons() {
301 let timer = TimerWheel::with_defaults();
302
303 let tasks: Vec<_> = (0..5)
305 .map(|_| TimerTask::new(Duration::from_secs(10), None))
306 .collect();
307
308 let batch = timer.register_batch(tasks);
309 let task_ids: Vec<_> = batch.task_ids.clone();
310 let mut receivers = batch.into_completion_receivers();
311
312 timer.cancel_batch(&task_ids[0..3]);
314
315 for rx in receivers.drain(0..3) {
317 let result = rx.await.expect("Should receive completion notification");
318 assert_eq!(result, TaskCompletionReason::Cancelled);
319 }
320
321 timer.cancel_batch(&task_ids[3..5]);
323 for rx in receivers {
324 let result = rx.await.expect("Should receive completion notification");
325 assert_eq!(result, TaskCompletionReason::Cancelled);
326 }
327 }
328}