Module: Pgbus::RetryBackoff

Defined in:
lib/pgbus/retry_backoff.rb

Overview

Computes exponential backoff delays for the VT-based retry path (unhandled exceptions that fall through ActiveJob’s retry_on).

The formula mirrors the CircuitBreaker pattern already used elsewhere in pgbus: base * 2^(attempt-1), capped at max, with optional jitter to prevent thundering-herd retries.

Jobs can override the global config via the pgbus_retry_backoff class-level DSL (see JobMixin below).

Defined Under Namespace

Modules: JobMixin

Class Method Summary collapse

Class Method Details

.compute_delay(attempt:, base: nil, max: nil, jitter: nil) ⇒ Integer

Core backoff computation.

Parameters:

  • attempt (Integer)

    1-based retry attempt number (read_ct - 1)

  • base (Numeric) (defaults to: nil)

    base delay in seconds (default: config.retry_backoff)

  • max (Numeric) (defaults to: nil)

    maximum delay cap (default: config.retry_backoff_max)

  • jitter (Numeric) (defaults to: nil)

    jitter factor 0..1 (default: config.retry_backoff_jitter)

Returns:

  • (Integer)

    delay in seconds



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/pgbus/retry_backoff.rb', line 67

def compute_delay(attempt:, base: nil, max: nil, jitter: nil)
  config = Pgbus.configuration
  base ||= config.retry_backoff
  max ||= config.retry_backoff_max
  jitter = config.retry_backoff_jitter if jitter.nil?

  exponent = [attempt - 1, 0].max
  delay = base * (2**exponent)
  delay = [delay, max].min

  [apply_jitter(delay, jitter), max].min
end

.compute_delay_for_job(job_class, attempt:, jitter: nil) ⇒ Object

Compute delay for a specific job class, falling back to global config for any options not overridden at the job level.



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/pgbus/retry_backoff.rb', line 47

def compute_delay_for_job(job_class, attempt:, jitter: nil)
  overrides = (job_class.respond_to?(:pgbus_retry_backoff_config) &&
              job_class.pgbus_retry_backoff_config) || {}

  config = Pgbus.configuration
  compute_delay(
    attempt: attempt,
    base: overrides[:base] || config.retry_backoff,
    max: overrides[:max] || config.retry_backoff_max,
    jitter: jitter || overrides[:jitter] || config.retry_backoff_jitter
  )
end