///|
pub fn Wheel::snapshot(self : Wheel) -> TimerSnapshot {
{
now: self.current_tick,
next_id: self.next_id,
next_sequence: self.next_sequence,
fired_total: self.fired_total,
scheduled_total: self.scheduled_total,
cascades_total: self.cascades_total,
config: self.config,
timers: self.timers(),
}
}
///|
fn snapshot_has_duplicate_ids(snapshot : TimerSnapshot) -> Bool {
let seen : Map[Int, Bool] = Map([])
for timer in snapshot.timers {
if seen.contains(timer.id) {
return true
}
seen[timer.id] = true
}
false
}
///|
pub fn Wheel::restore(snapshot : TimerSnapshot) -> Wheel? {
if !snapshot.config.is_valid() ||
snapshot.now < 0 ||
snapshot.next_id < 1 ||
snapshot.next_sequence < 1 ||
snapshot_has_duplicate_ids(snapshot) {
return None
}
let wheel = Wheel::new(config=snapshot.config)
wheel.current_tick = snapshot.now
wheel.next_id = snapshot.next_id
wheel.next_sequence = snapshot.next_sequence
wheel.fired_total = snapshot.fired_total
wheel.scheduled_total = snapshot.scheduled_total
wheel.cascades_total = snapshot.cascades_total
for info in snapshot.timers {
if info.id <= 0 || (info.repeat != RepeatMode::Once && info.period <= 0) {
return None
}
let timer = InternalTimer::{
id: info.id,
deadline: info.deadline,
period: info.period,
repeat: info.repeat,
payload: info.payload,
state: info.state,
sequence: info.sequence,
generation: info.generation,
occurrence: info.occurrence,
}
wheel.timers[info.id] = timer
if timer.state == TimerState::Pending {
wheel.place(timer)
}
}
Some(wheel)
}
///|
pub fn TimerSnapshot::to_json(self : TimerSnapshot) -> String {
let out = StringBuilder()
out.write_string(
"{\"now\":\{self.now},\"next_id\":\{self.next_id},\"next_sequence\":\{self.next_sequence},\"fired_total\":\{self.fired_total},\"scheduled_total\":\{self.scheduled_total},\"cascades_total\":\{self.cascades_total},\"config\":{\"tick_ms\":\{self.config.tick_ms},\"slots_per_level\":\{self.config.slots_per_level},\"levels\":\{self.config.levels},\"max_catch_up\":\{self.config.max_catch_up}},\"timers\":[",
)
for index, timer in self.timers {
if index > 0 {
out.write_char(',')
}
out.write_string(timer.to_json())
}
out.write_string("]}")
out.to_string()
}