A Simple Guide to Background Jobs in Ruby on Rails

As any Ruby on Rails application grows, sooner or later, you will find yourself needing to perform some tasks asynchronously, outside the main request-response cycle. And this is when background jobs come into play. Here, the background jobs allow you to offload your time-consuming task, and thereby ensuring your web application remains responsive and efficient.

Background jobs in Ruby on Rails are like implementing the old saying "while waiting for the rain to stop". This blog post will explore the basic concepts behind background jobs, explain why they are important, and also demonstrate a simple example of how to use them.

Why Use Background Jobs?

Suppose you have some Rails application that is actually sending emails to users. If you're sending the email during the request-response cycle, then the user will have to wait for this email to be sent before your page loads. This makes your application slow and unresponsive. Background jobs help out here by moving such tasks to another process so that the user doesn't have to wait.

Process of Sending Emails in background jobs

Some of the common use cases of background jobs include:

  • Sending emails: Sending emails can be pricey for most applications. Background jobs will ensure that the process of sending emails never blocks or interferes with the user interface.
  • Processing uploads: Uploading or resizing images may take a considerable amount of time. Offloading this to a background job allows the interface to remain responsive while it is at work.
  • Generating reports: Generating most reports tends to be expensive in terms of resources. In the case of background jobs, users are able to initiate the creation of a report and then return when the report is ready.
  • Data sync with third-party services: This is the process of syncing with external APIs and long-running data processes, which, in RoR development services, is made possible by using background jobs. Thus, the handling of data operations is done without any interruption of a user's interaction.

Setting Up Background Jobs in Rails

Rails provides several gems to handle background jobs, with the most popular being Sidekiq because of its popularity and performance.

  1. Start by adding Sidekiq to your application's Gemfile:
gem 'sidekiq'
  1. Next, run bundle install:
bundle install
  1. Next, we need to configure Sidekiq. Open config/application.rb file and add the following line inside the application class definition:
config.active_job.queue_adapter = :sidekiq

How Sidekiq Works ?

  1. Job Creation: In Ruby on Rails Sidekiq, a job object—typically a Ruby class—is serialized into JSON format when it is enqueued. After this, a serialized job is kept in redis list , which serves as hob's queue
  2. Redis: An in-memory data structure storage is called Redis (Remote Dictionary Server) is a major component of Rails Sidekiq's backend. Redis offers work queue and metadata storage that is quick and effective.
  3. Workers(A worker is a class that performs the background job): Sidekiq executes many worker processes simultaneously. These workers execute and constantly retrieve jobs from the Redis queues. To effectively wait for new jobs, workers use a blocking pop operation on the Redis list.for instance: generate the worker:
 rails generate sidekiq:worker WelcomeEmail

This command creates a file at app/workers/welcome_email_worker.rb with the following content:

 class WelcomeEmailWorker
   include Sidekiq::Worker

   def perform(user_id)
     user = User.find(user_id)
     UserMailer.with(user: user).welcome_email.deliver_now
   end
 end

In this example, the perform method finds the user by user_id and sends a welcome email using a mailer.

  1. Concurrency: With Sidekiq, you may manage how many workers are operating at once. You can set up numerous workers to operate concurrently, allowing for the concurrent execution of multiple jobs. Each worker process can only perform one job at a time.Next, you'll need to configure Sidekiq. Create a new file called sidekiq.yml in the config directory with the following content:
 yaml
 :concurrency: 5
 :queues:
   - default

This configuration sets the concurrency level to 5, meaning Sidekiq will process up to 5 jobs simultaneously.

  1. Retries and Failures: Sidekiq has built-in procedures to deal with unsuccessful job attempts. When a job runs into an exception, Sidekiq retries it using user-configurable retry settings. Rails Active Job ensures that if the job continues to fail after all retries, Sidekiq moves it to a dead letter queue or logs the failure for detailed inspection, providing a robust mechanism for error handling.
 class WelcomeEmailWorker
   include Sidekiq::Worker
   sidekiq_options retry: 5  # Retry 5 times

   def perform(args)
     # Job logic here
   end
 end

You can configure the retry behavior in your worker class or globally in the Sidekiq configuration.

  1. Concurrency Control: With Sidekiq, you can set queue priorities and manage the concurrency of each queue separately. This ensures that higher-priority queues are processed before lower-priority ones.You can configure queue prioritization in the Sidekiq configuration file (sidekiq.yml) or directly in your Sidekiq initialization code.
 :queues:
   - [critical, 5]
   - [default, 1]
   - [low, 1]

Sidekiq will process jobs from the critical queue five times more frequently than from the default and low queues.

  1. Scheduled Jobs: Jobs that can be scheduled for later execution are supported by Sidekiq. Time stamp principles are used as scores in a Redis sorted set that is used to keep track of jobs. Scheduled jobs are checked and verified for by Sidekiq's clock process, which then places them in the relevant queues for execution.
 @user = User.new(user_params)
 WelcomeEmailWorker.perform_in(5.minutes, @user.id)
  1. Monitoring and Dashboard in Sidekiq: A web-based interface called the Sidekiq web dashboard gives you access to real-time information about your Sidekiq task processing system.
 # config/routes.rb
 require 'sidekiq/web'
 mount Sidekiq::Web => '/sidekiq'

Several views and metrics are available through this interface, including:

(i) Queues: Shows the number of jobs in each state (processing, waiting, etc.), as well as the list of queues and their sizes.
(ii) Workers: Displays the active workers along with the jobs they are handling at the moment.
(iii) Retries: This is a list of jobs that are scheduled for retry after failing.
(iv) Scheduled: Shows jobs that are scheduled to execute at a later time.
(v) Dead: Displays jobs that are in the Dead Letter Queue because they have failed and have used up all possible retries.

Conclusion

Background jobs form an essential part of making scalable and responsive Ruby on Rails applications. Incorporating Ruby on Rails background jobs, especially by using Sidekiq, will really boost the performance of your application and give output responsiveness. Sending long-running tasks off to be executed elsewhere frees up a web app to scale while keeping users happy. In this guide, we walked through the basics of setting up and using Sidekiq for background jobs in Ruby on Rails. If you're looking for expert assistance in implementing such solutions, consider working with an agile Ruby on Rails development company like Bluebash.

Want to hire Ruby on Rails developers for your project or perhaps tap into the power of the Ruby on Rails framework? Find the best Ruby on Rails software development company. Unleash the full potential of your applications with Sidekiq and background jobs.