RM

Ravi Menon · Cap backoff at one minute

18 lines

  1. import type { Job, JobHandler } from './types'
  2. // Wait 1s, 2s, 4s... capped at one minute.
  3. export function backoff(attempts: number) {
  4. return Math.min(2 ** attempts * 1000, 60_000)
  5. }
  6. export function withRetry<Payload>(handler: JobHandler<Payload>, maxAttempts = 5): JobHandler<Payload> {
  7. return async (job: Job<Payload>) => {
  8. try {
  9. await handler(job)
  10. } catch (error) {
  11. if (job.attempts + 1 >= maxAttempts) throw error
  12. await new Promise(resolve => setTimeout(resolve, backoff(job.attempts)))
  13. await withRetry(handler, maxAttempts)({ ...job, attempts: job.attempts + 1 })
  14. }
  15. }
  16. }