Skip to main content

reifydb_runtime/actor/timers/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	fmt,
6	fmt::Debug,
7	sync::{
8		Arc,
9		atomic::{AtomicBool, AtomicU64, Ordering},
10	},
11};
12
13#[cfg(reifydb_target = "dst")]
14pub(crate) mod dst;
15#[cfg(reifydb_target = "native")]
16pub mod scheduler;
17#[cfg(reifydb_target = "wasi")]
18pub(crate) mod wasi;
19#[cfg(reifydb_target = "wasm")]
20pub(crate) mod wasm;
21
22#[cfg(reifydb_target = "wasi")]
23use wasi::drain_expired_timers as wasi_drain;
24
25/// Handle to a scheduled timer.
26///
27/// Can be used to cancel the timer before it fires.
28#[derive(Clone)]
29pub struct TimerHandle {
30	id: u64,
31	cancelled: Arc<AtomicBool>,
32}
33
34impl TimerHandle {
35	pub(crate) fn new(id: u64) -> Self {
36		Self {
37			id,
38			cancelled: Arc::new(AtomicBool::new(false)),
39		}
40	}
41
42	/// Cancel this timer.
43	///
44	/// If the timer hasn't fired yet, it will be cancelled.
45	/// Returns `true` if the timer was successfully cancelled.
46	pub fn cancel(&self) -> bool {
47		self.cancelled.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst).is_ok()
48	}
49
50	/// Check if this timer has been cancelled.
51	pub fn is_cancelled(&self) -> bool {
52		self.cancelled.load(Ordering::SeqCst)
53	}
54
55	/// Get the timer ID.
56	pub fn id(&self) -> u64 {
57		self.id
58	}
59
60	/// Get a clone of the cancelled flag.
61	pub(crate) fn cancelled_flag(&self) -> Arc<AtomicBool> {
62		self.cancelled.clone()
63	}
64}
65
66impl Debug for TimerHandle {
67	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68		f.debug_struct("TimerHandle").field("id", &self.id).field("cancelled", &self.is_cancelled()).finish()
69	}
70}
71
72/// Counter for generating unique timer IDs.
73static TIMER_ID_COUNTER: AtomicU64 = AtomicU64::new(0);
74
75pub(crate) fn next_timer_id() -> u64 {
76	TIMER_ID_COUNTER.fetch_add(1, Ordering::Relaxed)
77}
78
79/// Drain expired timers, firing their callbacks synchronously.
80///
81/// Only meaningful on WASI where timers are queue-based. No-op on native
82/// (thread-based timers) and WASM (JavaScript event loop handles timers).
83#[cfg(reifydb_target = "wasi")]
84pub fn drain_expired_timers() {
85	wasi_drain();
86}
87
88/// Drain expired timers (no-op on this platform).
89#[cfg(not(reifydb_target = "wasi"))]
90pub fn drain_expired_timers() {}