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.
# for Active Job Inline
Rails.application.config.active_job.queue_adapter = :inline
# for Active Job Async
Rails.application.config.active_job.queue_adapter = :async
In Rails 4.x the default queue adapter is :inline
. In Rails 5 it has
been changed to
:async
by DHH.
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.
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.
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.
test "order is created successfully" do
# Code to test record in orders table is created
end
test "order email is sent" do
# Code to test order email is sent
end
The process of sending email can be part of a job which is invoked from an
after_create
callback in Order
model.
class Order < ActiveRecord::Base
after_create :send_order_email
def send_order_email
# Invoke the job of sending an email asynchronously.
end
end
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.
If this blog was helpful, check out our full blog archive.