Recurring Job Scheduler
MediumScheduling · Citadel
Implement scheduled_job_runs(jobs, dependencies), which simulates a scheduler for recurring jobs and returns every run it performs.
Inputs
jobsis a list of[job_id, start, interval, count].job_idis a unique string. The job must run exactlycounttimes.dependenciesis a list of[before, after]pairs: jobaftermay not run at all until jobbeforehas run at least once.
Scheduling rules
- A job's first run is due at time
start. Every later run is dueintervaltime units after the job's previous actual run (so a delayed run shifts all later runs). - Runs take no time. A run is *ready* at its due time if each of its prerequisites has already run at least once. If not, it waits, and becomes ready at the exact moment its last missing prerequisite runs.
- Whenever several runs are ready at the same time, the scheduler executes the one with the smallest
job_id(normal string comparison) first. A run that becomes ready during a timestamp (because a prerequisite just ran) joins the runs still waiting at that timestamp.
Return a list of [time, job_id] records, one per run, in the order the runs are executed.
Example 1
- Input:
- jobs = [["report", 0, 10, 2], ["etl", 5, 10, 2], ["backup", 0, 4, 3]], dependencies = [["etl", "report"]]
- Output:
- [[0, "backup"], [4, "backup"], [5, "etl"], [5, "report"], [8, "backup"], [15, "etl"], [15, "report"]]
- Explanation
reportis due at 0 butetlhas not run yet, so it waits;backupruns at 0, 4 and 8.etlfirst runs at 5, which releasesreportat 5 too. Each later run is due one interval after the previous actual run, soreportruns again at 15 (not 10), right afteretl's second run.
Example 2
- Input:
- jobs = [["b", 0, 5, 1], ["a", 0, 5, 1]], dependencies = [["b", "a"]]
- Output:
- [[0, "b"], [0, "a"]]
- Explanation
- Both are due at 0 and
ahas the smaller id, but it is blocked untilbruns. Oncebruns at 0,abecomes ready at that same time and runs immediately after it.
Example 3
- Input:
- jobs = [["x", 3, 2, 2], ["y", 0, 1, 3]], dependencies = [["x", "y"]]
- Output:
- [[3, "x"], [3, "y"], [4, "y"], [5, "x"], [5, "y"]]
- Explanation
yis due at 0 but cannot run untilxfirst runs at 3.ythen runs at 3, 4 and 5; at time 5 bothxandyare ready, soxgoes first by id.
Constraints
1 <= jobs.length <= 10^41 <= count, and the sum of allcountvalues is at most10^50 <= start <= 10^9,1 <= interval <= 10^60 <= dependencies.length <= 2 * 10^4- Every job id in
dependenciesappears injobs, and the dependencies contain no cycle