5. Scheduling

Batched Update Scheduling

midfrontend-internalsscheduling

If a single event handler triggers three separate state updates, naively re-rendering once per update would do 3x the work for a result the user only ever sees once (the DOM only updates before the next paint anyway). Both React and Vue solve this the same way: don't run an update immediately -- QUEUE it, deduplicated by "job identity" (the same component's pending re-render, requested three times, is still only ONE pending job), then run the whole queue together on the next tick.

A "job" is any hashable callable -- calling it performs the actual update. Implement:

  • Scheduler.schedule(job) -- add job to the pending queue, UNLESS it's already queued (the same job object scheduled twice before the next flush must not be queued twice).
  • Scheduler.flush() -- run every currently queued job exactly once, in the order it was first scheduled this round, then clear the queue so the next schedule() calls start fresh. A job that schedules ANOTHER job as a side effect of running (schedule() called from inside a job's own callback) must NOT have that new job run in this same flush() call -- it waits for the next explicit flush().

flush() stands in for the real microtask tick (real Vue schedules a flush via Promise.resolve().then(...); this exercise uses an explicit method call the test invokes directly instead of a real microtask).

Example

scheduler = Scheduler()
render_count = 0
def rerender():
    global render_count
    render_count += 1

scheduler.schedule(rerender)
scheduler.schedule(rerender)   # same job -- deduplicated
scheduler.schedule(rerender)   # same job -- deduplicated
scheduler.flush()
render_count   # -> 1, not 3

Constraints

  • Dedup is by job IDENTITY (the same callable object), not by anything about what the job does.
  • flush() on an empty queue must not raise.
  • A job scheduled while flush() is running must be picked up by the NEXT flush() call, never the current one.

Real-world grounding

Real Vue's queue is additionally sorted by component tree depth before flushing (so a parent's update always runs before its children's, never the reverse) and guards against infinite self-rescheduling loops with a recursion limit -- this exercise implements the core dedup-then-batch- flush mechanism underneath both.

hints
batch_scheduler.pysign in to run
Loading...
test result

This is a preview. Sign in to run this exercise against the real tests.