sajad torkamani

What is Active Job?

Active Job is Rails’s framework for declaring jobs and making them run on a variety of queuing backends (SidekiqResque, etc). These jobs can be things like scheduled backups of uploaded files, report generation, billing, emails, and more.

Active Job provides a unified and expressive API that makes it easy to integrate with different queuing back-ends. You can switch between queuing back-ends without changing how you interact with the Active Job API.

Active Job is also used for Action Mailers’s #deliver_later functionality to allow enqueuing emails as a background job that can run outside the HTTP request-response lifecycle.

Rails’ default queuing implementation

Rails provides a default queuing system that runs jobs asynchronously in an in-process thread pool. This is not intended for production use since jobs will be dropped if the process crashes or the Rails application server restarts.

Create a job

 ./bin/rails g job send_reminders

This will create:

  • spec/jobs/send_reminders_job_spec.rb
  • app/jobs/send_reminders_job.rb

A default generated job looks like this:

# frozen_string_literal: true

class SendRemindersJob < ApplicationJob
  queue_as :default

  def perform(*args)
    # Do something later
  end
end

Enqueue a job

Enqueue a job to be performed as soon as the queuing system is free:

SendRemindersJob.perform_later

Enqueue a job to be performed tomorrow at noon:

SendRemindersJob.set(wait_until: Date.tomorrow.noon).perform_later(guest)

Enqueue a job to be performed 1 week from now:

SendRemindersJob.set(wait: 1.week).perform_later(guest)

Pass params to perform method of job:

SendRemindersJob.perform_later(some_user, "some message")

Configure queuing back-end

ActiveJob has adapters for multiple back-ends (see list). You can set your default queuing back-end in config/application.rb or config/<environment>.rb:

# config/application.rb
module YourApp
  class Application < Rails::Application
    # Be sure to have the adapter's gem in your Gemfile
    # and follow the adapter's specific installation
    # and deployment instructions.
    config.active_job.queue_adapter = :sidekiq
  end
end

Or, on a per-job basis:

class SendRemindersJob < ApplicationJob
  self.queue_adapter = :resque
  # ...
end

# Now your job will use `resque` as its backend queue adapter, overriding what
# was configured in `config.active_job.queue_adapter`.

You’ll need to start the queuing back-end in another process that runs parallel to your Rails application server. Consult the docs for your back-end of choice. Here are the docs for some popular back-ends:

Queues

Most queuing-backends support multiple queues. This means you can enqueue jobs on different queues (e.g., low_priority, high_priority, emails, reminders, etc):

class SendRemindersJob < ApplicationJob
  queue_as :low_priority
  # ...
end

You can set queue name prefixes based on the Rails environment:

# config/application.rb
module YourApp
  class Application < Rails::Application
    config.active_job.queue_name_prefix = Rails.env
  end
end

Now, your queues will be named something like staging_low_priority and production_low_priority.

Job callbacks

You can run custom code during the lifecycle of a job. Here are the available callbacks:

More links & further reading

Sources

Tagged: Rails