Build a Concurrent Recurring Job Scheduler
Company: Nuro
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
# Build a Concurrent Recurring Job Scheduler
Design a thread-safe `JobScheduler` that can schedule a callable to run repeatedly at a requested interval and later deschedule it. The public API should support `schedule(job_id, fn, interval_seconds)` and `deschedule(job_id)`. Explain the core data structures, worker coordination, cancellation semantics, shutdown, and how you would test races.
### Constraints & Assumptions
- Multiple threads may schedule and deschedule jobs concurrently.
- A descheduled job must not start again, but a callable already running is allowed to finish.
- An invocation is considered started when the scheduler atomically transitions it to `RUNNING` under its registry lock. If that transition wins the race, deschedule may return before the executor enters the user callable, but that already-started invocation is allowed to run.
- Callables may raise or run longer than their configured interval.
- Waiting should be efficient; busy polling is not acceptable.
### Clarifying Questions to Ask
- Is the recurrence fixed-rate or fixed-delay, and should missed runs be skipped or caught up?
- May two invocations of the same job overlap?
- Does scheduling an existing `job_id` replace it or fail?
- What guarantees should `deschedule` provide when racing with dispatch?
### Solving Hints
Separate deciding what is due from executing user callables. Use monotonic time, and make stale queued entries harmless when a job is replaced or canceled.
### What a Strong Answer Covers
- A min-heap of next-run times, a job registry, and condition-variable coordination.
- A precise linearization point for schedule and deschedule operations.
- Generation tokens or equivalent protection against stale heap entries and cancellation races.
- Execution outside locks, bounded worker resources, exception isolation, and shutdown behavior.
- Deterministic concurrency tests using fake time, barriers, and events.
### Follow-up Questions
- How would you persist schedules across process restarts?
- How would you prevent one long-running job from starving others?
- What changes in a distributed scheduler with multiple scheduler instances?
Quick Answer: Design a thread-safe recurring job scheduler with concurrent schedule and deschedule operations. Specify timing semantics, cancellation races, stale entries, worker coordination, exception isolation, shutdown, and deterministic concurrency tests.