pub struct Periodic<H, C: TimerConfig = BoxedTimers, Store: SlabStore<Item = WheelEntry<C::Storage>> = UnboundedSlab<WheelEntry<Box<dyn Handler<Instant>>>>> { /* private fields */ }Expand description
Periodic timer wrapper — automatically reschedules after each firing.
Generic over the concrete handler type H — no nesting, no type erasure
overhead. When stored in a wheel, the Periodic<H, C, Store> is wrapped
in C::Storage (e.g. Box<dyn Handler<Instant>>) once at the outermost
level. The inner handler H is stored directly, not wrapped.
This means Periodic<H> is size_of::<H>() + size_of::<Duration>() plus
a small marker — compact enough to fit in inline storage (FlatVirtual)
alongside typical handlers.
§Scheduling
schedule_forget is used for
rescheduling. On bounded wheels, this panics if the slab is at capacity.
This is a capacity planning error — size your wheel for peak concurrent
timers including periodic overhead. See the store
module documentation for the OOM-as-panic rationale.
§Cancellation
If the periodic timer is cancelled (via cancel)
or dropped during shutdown, the inner handler is dropped normally — no leak.
§Example
use std::time::{Duration, Instant};
use nexus_rt::{IntoHandler, ResMut};
use nexus_rt::timer::{Periodic, TimerWheel};
fn heartbeat(mut counter: ResMut<u64>, _now: Instant) {
*counter += 1;
}
let handler = heartbeat.into_handler(world.registry());
let periodic = Periodic::new(handler, Duration::from_millis(100));
world.resource_mut::<TimerWheel>()
.schedule_forget(Instant::now(), Box::new(periodic));Implementations§
Source§impl<H, C: TimerConfig, Store: SlabStore<Item = WheelEntry<C::Storage>>> Periodic<H, C, Store>
impl<H, C: TimerConfig, Store: SlabStore<Item = WheelEntry<C::Storage>>> Periodic<H, C, Store>
Sourcepub fn new(handler: H, interval: Duration) -> Self
pub fn new(handler: H, interval: Duration) -> Self
Create a periodic wrapper around a handler.
C and Store determine how the handler is stored in the wheel
and which wheel resource to look up on reschedule. Defaults are
BoxedTimers + UnboundedSlab — override via type annotation or
turbofish for inline/bounded configurations.
§Example
// Boxed + unbounded (defaults)
let p = Periodic::new(handler, Duration::from_millis(100));
// Inline + unbounded (Store must be specified when C changes)
use nexus_timer::store::UnboundedSlab;
let p: Periodic<_, InlineTimers, UnboundedSlab<_>> =
Periodic::new(handler, Duration::from_millis(100));Sourcepub fn into_inner(self) -> Option<H>
pub fn into_inner(self) -> Option<H>
Unwrap the inner handler, if present.
Returns None only during the transient state inside
Handler::run (after fire, before reschedule).