Migrate from Resque to Sidekiq

I couldn’t believe it’s been 6 months since my last programming related blog post. I’ve been busy taking photos lately intead (see my photo blog here).

Back to some Ruby. Today I finally made the decision to spend some time in the current sprint to migrate our background processing gem from Resque to Sidekiq. Not that Resque is doing anything particularly wrong, it’s just the Resque setup code was done by me about 3 years ago (not long after I just started working full time on Ruby), and the setup has been copied from project to project, but never improved. After reading so many good things about Sidekiq, I thought I’ll give Sidekiq a try.

First thing first, Gemfile.

# gem 'resque',                           require: 'resque/server'
# gem 'resque-scheduler',                 '~> 2.0.0', require: 'resque_scheduler'
# gem 'resque_mailer',                    '~> 2.2.1'

gem 'sidekiq',                            '~> 3.0.0'
gem 'sinatra',                            require: false
gem 'devise-async'

and bundle install it.

Next a global search on Resque.enqueue and replace with Sidekiq::Client.enqueue.

Then go to the old Resque worker classes to find @queue = :abc and replace with include Sidekiq::Worker. Of course, as the awesome Sidekiq doc points out, turn def self.perform into def perform

For mailer classes, in my old Resque setup, I use the resque_mailer gem and have the following async_mailer.rb, which gives me a good super class for any async mailer classes that can extend from.

class AsyncMailer < ActionMailer::Base
  include Resque::Mailer

  private

  def mail_header(subject)
    {to:       @user.email,
     from:     Settings.mail.from,
     reply_to: Settings.mail.reply_to,
     subject:  subject}
  end

end

I simply took out the include Resque::Mailer line from AsyncMailer. Another global search on .deliver to find all application codes that send out emails. For all the matches, simply change the email deliver call to use the Sidekid’s Delayed extension syntax for ActionMailer.

More hacks required to make the Devise mailer happy.

In devise.rb initializer, add config.mailer = 'Devise::Async::Proxy'. Yes, I’m using a very old version of Devise …

Create a new devise_async.rb under initializers, and add single line Devise::Async.backend = :sidekiq

Last, in routes.rb, replace the old Resque web admin interface with the Sidekiq equivalent, mount Sidekiq::Web, at: '/sidekiq'

That’s pretty much it. Of course, I had to do more work to make Heroku, Unicorn and Sidekiq all happy and live in harmony. That’ll be another topic for another post.

Published: 2014-04-25
blog comments powered by Disqus