Run background jobs with single process

on Rails, Sucker Punch, Heroku, Background Jobs

As we already know (almost?) that we should use background jobs to process long tasks (or even not so long task but can be processed later) to improve performance and user experience, a very common example is sending email.
We often use some gems like: Delayed Job, Sidekiq, Resque... So far so good with many features, such as: retrying, multiple queues, priority... but all of them have to use additional processes which lead to unusable on Heroku with only a free single dyno. In some cases, we just want to have a simple background job and want to run on a free heroku, these gems cannot be used.

Solution

Use Sucker Punch to run background job with single process (the process that is used for running web app).

Usage

  • Add gem 'sucker_punch', '~> 1.0' to your Gemfile, run bundle
  • Create a class (often ends with Job, example: EmailJob) which need to:
    • Include SuckerPunch::Job
    • Define instance method called perform
    • Should be in app/jobs directory (not required but should be)

Example:

#app/jobs/welcome_email_job.rb

class WelcomeEmailJob
  include SuckerPunch::Job

  def perform(user)
    UserMailer.welcome(user).deliver
  end
end
  • Run it: WelcomeEmailJob.new.async.perform(@user)
  • See the awesome thing

Conclusion

  • Use it when you need a simple solution for background jobs in a single process environment like heroku free dyno
  • Don'use it when you need advanced background jobs like: retrying, multiple queues, priority... or you need a high performance background jobs and keep the app run fast
  • Use ActiveJob if you are using rails 4.2+ to make it easily to switch the background job gem. Example: you can use Sucker Punch for staging environment (which run on heroku free dyno) and Delayed Job on production environment.

A full stack developer with Ruby on Rails as the main framework. Eager to learn and share.