Rails 5 changed Active Job default adapter to Async

Mohit Natoo

By Mohit Natoo

on March 29, 2016

This blog is part of our  Rails 5 series.

Active Job has built-in adapters for multiple queuing backends among which two are intended for development and testing. They are Active Job Inline Adapter and Active Job Async Adapter.

These adapters can be configured as follows.

1
2# for Active Job Inline
3Rails.application.config.active_job.queue_adapter = :inline
4
5# for Active Job Async
6Rails.application.config.active_job.queue_adapter = :async
7

In Rails 4.x the default queue adapter is :inline. In Rails 5 it has been changed to :async by DHH.

Asynchronous Execution

In case of inline, as the name suggests, execution of the job happens in the same process that invokes the job. In case of Async adapter, the job is executed asynchronously using in-process thread pool.

AsyncJob makes use of a concurrent-ruby thread pool and the data is retained in memory. Since the data is stored in memory, if the application restarts, this data is lost. Hence, AsyncJob should not be used in production.

Running in future

AsyncJob supports running the job at some time in future through perform_later. Inline executes the job immediately and does not support running the job in future.

Both Active Job Async and Active Job Inline do not support configuring priorities among queues, timeout in execution and retry intervals/counts.

Advantage of having Async as default adapter

In Rails 4.x where Inline is the default adapter, the test cases were mistakenly dependent on job's behavior that happens synchronously in development/testing environment. Using Async adapter ,by default, will help users have tests not rely on such synchronous behavior.

It's a step closer to simulating your production environment where jobs are executed asynchronously with more persistent backends.

Consider an example, where in an e-commerce site upon every order placed an email is sent.

1
2test "order is created successfully" do
3  # Code to test record in orders table is created
4end
5
6test "order email is sent" do
7  # Code to test order email is sent
8end
9

The process of sending email can be part of a job which is invoked from an after_create callback in Order model.

1
2class Order < ActiveRecord::Base
3
4  after_create :send_order_email
5
6  def send_order_email
7    # Invoke the job of sending an email asynchronously.
8  end
9
10end
11

When Inline adapter is used, any wrongly configured email settings will cause both the above tests to fail. This is because the process of sending the email happens within the process of order creation and any error in sending the email would kill the process if unhandled.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.