Background Tasks With Rufus Scheduler

This article will show you how to schedule background tasks using rufus-scheduler.


Published on:September 11, 2015

Introduction

Rufus-Scheduler is a handy gem that allows you to perform background jobs. Rufus-Scheduler is unique in that it runs in-process and requires no help from outside tools such as cron or database engines. In this article we will show you how to use rufus-scheduler in your Rails applications. Let's get started!

Rails Application Setup

In order to use Rufus Scheduler, we must first add the rufus-scheduler gem to our Gemfile. To do this, open up your Gemfile and add in the line listed below.

Gemfile:

gem 'rufus-scheduler'

Now run a bundle install to install the gem.

Terminal Commands:

bundle install

Great, now we need to create an initializer that will contain the jobs we wish to schedule. Create a new initializer called scheduler.rb in the config/initializers directory and add in the code listed below.

config/initializers/scheduler.rb:

require 'rufus-scheduler'

scheduler = Rufus::Scheduler::singleton

# jobs go below here.

Now we are ready to schedule jobs.

Scheduling Jobs

Rufus Scheduler provides a simple syntax for scheduling jobs. You can schedule both one time jobs and recurring jobs. One time jobs can be either scheduled at a specific time, or you can tell Rufus to wait a specific amount of time before running the job (a delayed job). For recurring jobs and delayed jobs, you can either use a simple plain English (30m = 30 minutes, etc.) format or you can use the cron format for scheduling jobs. For this article we'll focus on the English format.

Recurring Jobs

Scheduling recurring jobs is easy. Simply use the following format in your scheduler.rb file:

config/initializers/scheduler.rb:

scheduler.every '5s' do
	# do stuff
end

The code above would perform your background task every 5 seconds. The list below will give you an idea of what time units are supported.

s Example: 5s - seconds, specifies the number of seconds you wish to wait
m Example: 5m - the number of minutes you wish to wait
h Example: 5h - the number of hours you wish to wait
d Example: 5d - the number of days you wish to wait
w Example: 5w - the number of weeks you wish to wait
M Example: 5M - the number of months you wish to wait
y Example: 1y - the number of years you wish to wait

For example, the following code would tell Rufus you wish to schedule a job for every 11 and a half hours:

config/initializers/scheduler.rb:

scheduler.every '11h30m' do
	# do stuff
end

Scheduling Delayed Jobs

Scheduling a delayed job is easy. The syntax is similar to the recurring syntax listed above, but we use the .in method instead of .every. For example, the following code would run a task 4 hours after the server starts.

config/initializers/scheduler.rb:

scheduler.in '4h' do
	# do stuff
end

Scheduling Jobs for Specific Dates/Times

You can also schedule a job for a specific date and time. To do this we use the at method. For example, the following code would run at 12:01am on December 1st, 2015.

config/initializers/scheduler.rb:

scheduler.at '2015/12/01 00:01:00' do
  # do something
end

Important Caveats

  1. Because Rufus Scheduler runs in process, the scheduler will reset if your Rails server gets restarted. This means that the timer for your jobs will get reset, so don't count on any monthly or yearly jobs getting called. If you need to persist jobs across server resets, use a job backend. We will show you how to do this in another article
  2. Rufus does not work with Active Job
  3. Some additional setup is needed for production environments (see below).

Production Setup

Production servers require a bit of additional setup. On most production web servers, idle Ruby processes are killed. In order for Rufus to work, you'll need to stop this from happening. For Passenger/Nginx you can copy the following code below to your nginx.conf config file for your website after the line that says passenger_enabled on;.

nginx.conf:

passenger_spawn_method direct;
passenger_min_instances 1;
passenger_pool_idle_time 0;

Conclusion

Rufus-Scheduler is a simple, easy to use scheduler that provides great functionality. It can be used for stuff like sending emails, cleaning up temp files, and much more. If you have any questions/comments on this article, please leave a comment below. Thanks for reading!

Resources