rails/rails
Active Job
Active contributors: rafaelfranca, byroot, dhh
Purpose
Active Job is a unified API for declaring and running background jobs across a variety of queue backends. The framework defines the job class shape (perform, before_enqueue, retry_on, etc.); pluggable adapters connect Sidekiq, Resque, Solid Queue, GoodJob, Delayed Job, and others.
Source: activejob/lib/active_job/. ~4,700 lines of lib/ Ruby.
Directory layout
activejob/
├── lib/
│ └── active_job/
│ ├── base.rb # ActiveJob::Base
│ ├── arguments.rb # Argument serialization
│ ├── callbacks.rb
│ ├── configured_job.rb # MyJob.set(wait: 1.minute)
│ ├── continuable.rb / continuation/ # Resumable jobs
│ ├── core.rb
│ ├── enqueue_after_transaction_commit.rb
│ ├── enqueuing.rb
│ ├── exceptions.rb # retry_on / discard_on
│ ├── execution.rb
│ ├── instrumentation.rb
│ ├── log_subscriber.rb
│ ├── queue_adapter.rb
│ ├── queue_adapters/ # Built-in adapters
│ ├── queue_name.rb / queue_priority.rb
│ ├── railtie.rb
│ ├── serializers/ # Argument type serializers
│ ├── structured_event_subscriber.rb
│ ├── test_case.rb
│ └── test_helper.rb
└── activejob.gemspecKey abstractions
| Constant | File | Purpose |
|---|---|---|
ActiveJob::Base |
activejob/lib/active_job/base.rb |
Subclass for every job |
ActiveJob::Arguments |
activejob/lib/active_job/arguments.rb |
Serializes job arguments to a JSON-safe form |
ActiveJob::QueueAdapters::AbstractAdapter |
activejob/lib/active_job/queue_adapters/abstract_adapter.rb |
Base class for adapters |
ActiveJob::ConfiguredJob |
activejob/lib/active_job/configured_job.rb |
Result of MyJob.set(wait: 1.minute) |
ActiveJob::Continuation |
activejob/lib/active_job/continuation/ |
Step-based resumable jobs |
Built-in queue adapters
activejob/lib/active_job/queue_adapters/:
async_adapter.rb— runs jobs in a thread pool in-process (development default).inline_adapter.rb— runs jobs synchronously (test default).test_adapter.rb— captures jobs in arrays for assertions.backburner_adapter.rbdelayed_job_adapter.rbqueue_classic_adapter.rbresque_adapter.rbsneakers_adapter.rb
External adapters (Sidekiq, Solid Queue, GoodJob, Mission Control) live in their own gems and register via:
class ActiveJob::QueueAdapters::SidekiqAdapter
def enqueue(job)
# ...
end
endThe abstract_adapter.rb defines the contract: enqueue(job), enqueue_at(job, timestamp), and optionally enqueue_all(jobs) for batch enqueuing.
Job lifecycle
sequenceDiagram
participant App
participant Job as MyJob
participant Adapter as Queue Adapter
participant Worker
App->>Job: MyJob.perform_later(args)
Job->>Job: serialize arguments
Job->>Adapter: enqueue
Adapter-->>App: ok
Worker->>Adapter: poll
Adapter->>Worker: job payload
Worker->>Job: deserialize, perform_now
Job->>Job: callbacks → perform → callbacksArgument serialization
ActiveJob::Arguments (activejob/lib/active_job/arguments.rb) walks job arguments and converts them to JSON-safe types:
- Primitives (
String,Integer, etc.) pass through. Symbol,Date,DateTime,Time,BigDecimal,Range, etc. are serialized via custom serializers inactivejob/lib/active_job/serializers/.- Active Record objects use
GlobalID::Identificationso aUseris serialized asgid://app/User/123and re-fetched on the worker side.
Custom types can be supported by subclassing ActiveJob::Serializers::ObjectSerializer.
Retries and discards
activejob/lib/active_job/exceptions.rb:
retry_on ExceptionClass, wait: 5.seconds, attempts: 5— exponential backoff and policy.discard_on ExceptionClass— drop without retry.rescue_from— handle insideperform.
The wait: argument supports a Proc or the symbol :polynomially_longer for adaptive backoff.
enqueue_after_transaction_commit
activejob/lib/active_job/enqueue_after_transaction_commit.rb is the integration point that delays enqueue until any wrapping Active Record transaction commits. This avoids the classic race where a worker tries to load a record before the inserting transaction is visible. Configured per-job; default depends on config.active_job.enqueue_after_transaction_commit.
Continuations
activejob/lib/active_job/continuation/ is a recently-added subsystem for resumable jobs. A long-running job can checkpoint after each step and, if the worker is killed (deploy, OOM), resume from the last completed step on the next attempt:
class ImportJob < ApplicationJob
include ActiveJob::Continuable
def perform(import_id)
step :extract do
...
end
step :transform do
...
end
step :load do
...
end
end
endImplementation: continuation.rb, continuable.rb, continuation/step.rb, continuation/state.rb. The continuation state is serialized into the job arguments.
Instrumentation
Active Job publishes:
enqueue.active_jobenqueue_at.active_jobenqueue_retry.active_jobperform_start.active_jobperform.active_jobdiscard.active_job
Subscribers in log_subscriber.rb and structured_event_subscriber.rb translate them into log lines.
Testing
ActiveJob::TestCase (activejob/lib/active_job/test_case.rb) and ActiveJob::TestHelper (test_helper.rb) provide:
assert_enqueued_with(job: MyJob, args: [1, 2])assert_enqueued_jobs nperform_enqueued_jobs do ... endassert_no_enqueued_jobs
By default tests use the :test adapter, which captures jobs in enqueued_jobs / performed_jobs arrays.
Integration points
- Active Record:
enqueue_after_transaction_committies enqueue to transaction commit.DestroyAssociationAsyncJobin Active Record uses Active Job fordependent: :destroy_async. - Action Mailer:
MailDeliveryJobis an Active Job subclass. - Action Mailbox:
RoutingJobandIncinerationJobroute inbound email via Active Job. - Active Storage: background analyses, transcoding, and purges are Active Jobs.
Entry points for modification
- Adding a queue adapter: subclass
ActiveJob::QueueAdapters::AbstractAdapter, implementenqueue/enqueue_at. Tests underactivejob/test/cases/queue_adapters/. - Adding an argument serializer: subclass
ActiveJob::Serializers::ObjectSerializer. Register onActiveJob::Serializers.add_serializers. - Adding a callback: declare via
before_enqueue,around_performetc. (ActiveJob::Callbacks).
Related pages
- packages/active-record — destroy_async, after_commit enqueue.
- packages/action-mailer, packages/action-mailbox — email-related jobs.
- packages/active-storage — analysis and purge jobs.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.