Virtual-Clock Timer Scheduler (Go)
Topics: scheduling, priority queue, heap, discrete-event simulation
Problem
Event loops and simulators don't sleep on real wall-clock time — they keep a queue of pending
timers and a virtual clock the caller advances explicitly. Build that scheduler.
type Scheduler struct { /* ... */ }
func NewScheduler() *Scheduler
func (s *Scheduler) Add(id string, at int64)
func (s *Scheduler) Advance(now int64) []string
Add(id, at) schedules a timer to fire at virtual time at. The same id may be added
multiple times — each is an independent timer.
Advance(now) moves the clock to now and returns every timer with fire time ≤ clock, in
fire-time order. Same fire time → insertion order. Fired timers are removed (never refire).
- The clock only moves forward: if
now ≤ the current clock, the clock is unchanged.
- A timer added at or before the current clock is due immediately.
Add(c,30) Add(a,10) Add(b,20)
Advance(25) → [a b]
Advance(40) → [c]
Add(first,5) Add(second,5) Add(third,5)
Advance(5) → [first second third] (insertion order on ties)
A binary min-heap keyed on (fireTime, insertionSeq) makes both operations cheap: Add is a
heap.Push, and Advance keeps heap.Pop-ing while the root is due. Popping in a loop naturally
yields fire-time order with stable tie-breaking. Reach for container/heap.
Sign in to submit your solution.