Katkat

Design and Implement an In-Memory Job Scheduler for Delayed Jobs

Walmart LabsSoftware Engineer · Onsite

Last updated

Design and implement an in-memory job scheduler that runs submitted jobs after a delay and supports cancellation and shutdown. It tests choosing a structure ordered by due time, thread-safe coordination without busy waiting, worker concurrency, failure isolation and the trade-offs of recurring or persistent jobs.

Design and implement a job scheduler: a component that accepts jobs, each a piece of code together with when it should run, holds each job until its time comes, and then runs it. The task was asked in a coding round, so treat it as an implementation exercise: write working code for the core and explain your design choices as you go, rather than drawing a distributed architecture.

A possible interface (agree on the real one with your interviewer):

from typing import Callable

class JobScheduler:
 def __init__(self, num_workers: int): ...
 def schedule(self, job: Callable[[], None], delay_seconds: float) -> int: ...
 def cancel(self, job_id: int) -> bool: ...
 def shutdown(self) -> None: ...
  • schedule registers job to run once, delay_seconds from now, and returns an id for it.
  • cancel keeps a job that has not started from running, and reports whether it did.
  • shutdown stops the scheduler.

Constraints and Clarifications

  • Assume the scheduler lives in a single process, and jobs are code in that same process.
  • Not specified: whether jobs repeat, how many may run at once, what happens when a job fails, and whether pending jobs must survive a restart. Ask, or state your assumptions.

Clarifying Questions

  • Are jobs one-off only, or can they repeat at a fixed interval or on a calendar schedule?
  • Should jobs run in parallel on a pool of workers, and what happens when more jobs are due than there are free workers?
  • In what order should jobs due at the same moment run?
  • When a job raises an error, should the scheduler retry it, log it, or stop?
  • Can schedule and cancel be called from several threads at once, including from inside a running job?
  • Can a job be cancelled after it has started, and what should shutdown do with jobs that are pending or running?
  • Must pending jobs survive a process restart, or is in-memory state enough?

Hints

Hint 1

Keep the next job within reach: Most of the time the only question is which job is due next and how long until then. Choose a structure that answers it without scanning every pending job.

Hint 2

Do not sleep past an earlier job: Whatever waits for the next due time must not miss a job that is submitted during the wait with an earlier time than the one it is waiting for.

Follow-up questions

  • Add jobs that repeat every N seconds. How do you compute each next run time so that slow jobs or late dispatch do not make the schedule drift?
  • A few long-running jobs occupy every worker. How do you keep other due jobs from waiting behind them, and how would you notice the delay?
  • The scheduler must survive a process restart. What do you store, and at which moments?
  • Two copies of the service now run for availability. How do you keep a job from running twice?