Retrying Job Scheduler
Problem
Design RetryingJobScheduler to schedule one-time jobs and retry failed execution attempts. A claim identifies one execution attempt for a job.
Each job moves from waiting to running when claimed. A successful result ends its lifecycle, while a failed result gives the same job a new due time.
Requirements
- Registration.
schedulecreates a waiting job withdueAtequal torunAtandattemptNumber0. - Eligibility. A job is eligible exactly when it is waiting for its first attempt or a retry and
dueAt <= now; returned claim order is unspecified. - Claim attempts.
claimDuestarts every eligible job, increments itsattemptNumber, and returns oneClaimcontaining itsjobIdand new attempt number. A running job is not eligible. - Failure. Reporting failure keeps the same job and attempt number, then makes the job eligible again at
now + retryDelaySeconds; only the next claim increments the attempt number. - Success. Reporting success finishes the one-time job permanently, so it is never eligible again.
API
| Signature | Returns | Behavior |
|---|---|---|
RetryingJobScheduler(retryDelaySeconds: integer) | A new RetryingJobScheduler | Creates an empty scheduler with one fixed positive retry delay. |
schedule(jobId: string, runAt: integer) | void | Registers a one-time job. |
claimDue(now: integer) | Claim[] | Starts attempts for all eligible jobs and returns their claims. |
reportResult(jobId: string, succeeded: boolean, now: integer) | void | Resolves the job's active attempt. |
Claim has fields jobId: string and attemptNumber: integer.
Examples
Given RetryingJobScheduler(5):
| Call | Result |
|---|---|
schedule("email", 10) | No return value |
claimDue(9) | [] |
claimDue(10) | [Claim("email", 1)] |
claimDue(11) | [] |
reportResult("email", false, 12) | No return value |
claimDue(16) | [] |
claimDue(17) | [Claim("email", 2)] |
reportResult("email", true, 18) | No return value |
claimDue(100) | [] |
Constraints
1 <= retryDelaySeconds <= 1,000,000.0 <= runAt, now, dueAt <= 9,000,000,000,000,000.jobIdis nonempty, has at most 64 characters, and is compared by exact equality.- Each
jobIdis scheduled exactly once. - At most 1,000 jobs and 10,000 method calls occur in one testcase.
reportResultnames a running job.- Later
nowvalues do not decrease. - Calls outside these constraints are not judged.
Notes
All calls are sequential. Concurrency, recurring schedules, cancellation, workers, persistence, and distributed coordination are outside the contract.