Lightweight background processing for your Rails app

2015, Jul 14    

If you’ve ever used Rails Runner you know that it’s possible and actually quite easy to execute Ruby code in the context of Rails non-interactively. You do not need a user to click somewhere to invoke one of your app methods. However using ‘rails runner’ still requires you to type a command in the console and run it. What if you want your app to automatically perform scheduled tasks in the background? You can achieve this goal with cron, but it’s even easier with a simple, lightweight gem - Whenever. It’s easy to configure, works very good and does not have tons of dependencies, like a lot of Ruby gems tend to.

I’ve recently used Whenever gem to implement a specific user notifications system and it’s working surprisingly well. If you need some simple things to be done in the background, I believe Whenever is a good choice for you.

To install the gem you obviously open the console and run:

gem install whenever

or update your Gemfile with:

gem 'whenever', '~> 0.9.4'

Once you have the gem installed, the next step is to “wheneverize” your app by running:

wheneverize .

in the root directory of your application. That creates a config/schedule.rb file for you, which you’ll be using to take care of your app’s background tasks. Whenever have 3 types of tasks by default: rake, runner, and command, which are quite self-explanatory. To get the job done you simply “describe” the task in your schedule.rb file. Which very basic example may look like this:

set :environment, :development

every 1.minute do
  runner "YourAwesomeAutomaticTaskClass.MethodYouWantToRun"

and help the crontab to be up to date with the following command:

whenever --update-crontab you can, of course, check your cron file to make sure everything is fine by typing:

crontab -l

the result should be similar to this:

# Begin Whenever generated tasks for: /home/ozim/blog/config/schedule.rb
* * * * * /bin/bash -l -c 'cd /home/ozim/blog && bin/rails runner -e development '\''YourAwesomeAutomaticTaskClass.MethodYouWantToRun'\'''

Finally, if everything is fine, your scheduled tasks are now running in the background. YourAwesomeAutomaticTaskClass method is invoked every minute and let’s assume it adds a new record to your database. Now you can sit down, relax and check your database in 5 minutes, you should see the magic working.

Remember to restart your cron service to activate your newly added tasks:

sudo service cron restart
[sudo] password for ozim:
cron stop/waiting
cron start/running, process 27517

And, what is quite important, don’t forget to make sure your rails runner is executable:

chmod u+x bin/rails

Of course, the bin/rails need to be owned by the crontab user to make it all working.

You can find more info and documentation on the official gem page.