How to schedule Sidekiq jobs in Rails

2 minute read

The process is simple. You need the sidekiq-cron gem. The source and documentation is here. I suggest your read the documentation if the following quick guide does not work (because I am not going to maintain this one and you might be reading it at a time when these steps have become irrelevant).

Get the gem

Add this to your Gemfile:

gem 'sidekiq-cron'

And then run the following on the command line (from your Rails project root directory)

bundle install

The gem should be installed now.

Create a Worker

When you install sidekiq, it installs the generator too. If you don’t already have a Sidekiq job, you can run the following:

rails g sidekiq:worker MyFirst

This should create the file app/workers/my_first_worker.rb. Notice that the word Worker is attached to the file automatically. The file should contain this:

class MyFirstWorker
  include Sidekiq::Worker

  def perform(*args)
    # Do something
  end
end

Now let’s edit the file so it looks like:

class MyFirstWorker
  include Sidekiq::Worker

  def perform(*args)
    puts "Arguments: #{args}"
    puts "Time: #{Time.now}"
    if args.count.positive?
      puts args
    else
      puts 'nothing to do!'
    end
  end
end

Configure your Cron

Normally, you would do a MyFirstWorker.perform('argument') (or one of the other methods to schedule the job). But with a cron job, you need to make it work automatically. The gem we just added (sidekiq-cron) gets you the methods. What you need to do is to place the cron job when Rails boots up.

Edit your config/application.rb to add the following line inside the Application class:

Sidekiq::Cron::Job.create(
  name: 'My First Worker',
  cron: '*/5 * * * *',
  class: 'MyFirstWorker',
  args: %w[one two]
)

Of course you can also get this done using initializers if you do not want to pollute the application.rb file.

IMPORTANT

The documentation says that creating a YAML file and adding a config file can call your cron too, but that did not seem to work with me when I tried passing arguments.

Run the cron

There is nothing extra to be done. Just start rails server in one terminal console and then ask bundle to execute sidekiq using bundle exec sidekiq in another. You should get something like following on your sidekiq console every 5 minutes:

2018-11-28T07:57:07.890Z 16863 TID-owx63zp5z TranscodeWorker JID-c85f10b1fe6f7821f4c09074 INFO: start
Arguments: ["one", "two"]
Time: 2018-11-28 13:27:07 +0530
one
two
2018-11-28T07:57:07.893Z 16863 TID-owx63zp5z TranscodeWorker JID-c85f10b1fe6f7821f4c09074 INFO: done: 0.003 sec

Of course the job name and time would be different.

Tip

To check faster (every minute), change the cron: to * * * * * when creating the job.

Updated:

Leave a comment