When developing web applications, I often encounter a need of implementing some background jobs run regularly. With Ruby on Rails, we have many powerful gems helping us write background job, and sidekiq
is a good option. How about scheduling the job to run daily in certain time? You can use crontab
on server, set scheduler using curl
command to call an API. However, it requires you knowledge about system. Thanks towhenever
gem which makes our task much easier in Rails.
Dependencies
Sidekiq
is simple, efficient background processing which enqueues your jobs in Redis
using multiple threads to run as many jobs as it can in the same time.
Thus, in order to make it work, you will initially need to install Redis
on your server. Below is short version how to install Redis
on Ubuntu
server ( You can ignore this part if you installed Redis
before )
sudo apt-get update sudo apt-get install build-essential tcl cd /tmp curl -O http://download.redis.io/redis-stable.tar.gz tar xzvf redis-stable.tar.gz cd redis-stable make make test sudo make install sudo mkdir /etc/redis sudo cp /tmp/redis-stable/redis.conf /etc/redis sudo nano /etc/redis/redis.conf
Then, to continue, you need to update you config file
# /etc/redis/redis.conf # ... # change this line supervised no # to this line supervised systemd # And change this line dir . # To dir /var/lib/redis
After that, create redis systemd unit file
sudo nano /etc/systemd/system/redis.service
With below content
[Unit] Description=Redis In-Memory Data Store After=network.target
[Service] User=redis Group=redis ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf ExecStop=/usr/local/bin/redis-cli shutdown Restart=always
[Install] WantedBy=multi-user.target
What you need is to run some more commands to make it run
sudo adduser --system --group --no-create-home redis sudo mkdir /var/lib/redis sudo chown redis:redis /var/lib/redis sudo chmod 770 /var/lib/redis
# to start redis sudo systemctl start redis
# to enable redis at start boot sudo systemctl enable redis
Installing Gems
In this article I assume that you’ve already known at least basic Ruby on Rails. You will need to add these gems to your Gemfile
gem 'sidekiq' gem 'whenever'
Then, as usual, you need to run bundle install
Run sidekiq web
Before writing any Sidekiq worker, you can do some minor extra jobs to make its management board available on your website on url/sidekiq
require'sidekiq/web' Rails.application.routes.draw do mount Sidekiq::Web => '/sidekiq' # .... end
Create background jobs
By default, your Sidekiq
background jobs will be managed in app/workers
folder. Each job will have a separated worker class lying in a worker file. You can manually create workers
folder then create a worker class, or use worker generator
rails g sidekiq:worker Hard
The above command will generate HardWorker
class for you
class HardWorker include Sidekiq::Worker def perform(*args) # do something end end
In case you have a rake task, and you want to run the task in your background job
class HardWorker include Sidekiq::Worker def perform(*args) YourAppName::Application.load_tasks Rake::Task['YOUR_RAKE_TASK'].invoke end end
Schedule your job
Now, You already know how to setup your background job. It’s time to start scheduling your job with whenever
.
After installing the gem, you must run wheneverize .
to initialize whenever
for your application. This command will generate the file config/schedule.rb
It’s time to start writing your scheduler job
job_type :sidekiq, "cd :path && :environment_variable=:environment bundle exec sidekiq-client push :task :output"
every 30.minutes, :roles => [:app] do sidekiq "HardWorker" end
It’s all about writing scheduler job. Now, you need to update the scheduled jobs to system
whenever --update-crontab
You can see all cron jobs by crontab -l
or remove jobs by
crontab -r
Last but not least, you need to start you sidekiq
in order to run background jobs
bundle exec sidekiq -d -L log/sidekiq.log
Happy Coding!