Module: Delayed::Limitable

Extended by:
ActiveSupport::Concern
Defined in:
lib/delayed/limitable.rb

Overview

A mixin that wraps a class's perform method (or other methods named via on:) in Delayed::Limit.within_limit. It is automatically included in ActiveJob classes, and configures the job to retry with a polynomial backoff when the limit's wait_timeout would be exceeded:

class TouchesThirdPartyApiJob < ApplicationJob
with_limit :third_party_api, max: 100, per: 1.minute

def perform
  # ...
end
end

The 'purpose' defaults to the job's underscored class name, and the limit is registered via Delayed::Limit.register! (unless the purpose was already registered, e.g. in an initializer, in which case the max:/per: config may be omitted entirely). Multiple job classes may share a purpose (and its limit) as long as their configs match exactly.

Use on: to wrap one or more other instance methods instead of perform, e.g. if only a portion of the job's work is subject to the limit:

with_limit :third_party_api, max: 100, per: 1.minute, on: :deliver!

A class may declare with_limit more than once (e.g. to apply different limits to different methods), but only the first declaration defines the job's retry behavior (attempts, wait, and jitter, with wait_timeout acting as a floor on the computed wait). If two declarations' wait timeouts differ meaningfully, declare the one with the longer wait_timeout first.

Retries rely on ActiveJob's retry_on, so when this mixin is included in a plain (non-ActiveJob) class, the named methods are still wrapped in within_limit, but the class must define its own rescue/retry behavior for Delayed::Limit::LimitExceededError.

Constant Summary collapse

DEFAULT_RETRY_ATTEMPTS =
if defined?(ActiveJob) && ActiveJob.gem_version >= Gem::Version.new('7.0')
  :unlimited
else
  Float::INFINITY
end