Single Process Asynchronous Job with Sucker Punch

In a previous post we discussed about running asynchronous job with sidekiq. Sidekiq will spawn it’s workers processes and look for jobs on queue. But what if we don’t want to use separate processes to do asynchronous job?

Enter sucker punch.  Sucker punch enable us to do asynchronous processing within a single job.  This will reduce memory usage in your hosting and reduce hosting cost in Heroku. I use it often when I develop a mockup on Heroku free hosting.It won’t be wrong to call it a poor men’s sidekiq.

Sucker punch is simple to use. I just want to remind you to take special precaution when interacting with active record in an asynchronous process. Use ActiveRecord::Base.connection_pool.with_connection to not exhaust the connection in the ppol, as per the example in the readme:

# app/jobs/awesome_job.rb

class AwesomeJob
  include SuckerPunch::Job

  def perform(user_id)
    ActiveRecord::Base.connection_pool.with_connection do
      user = User.find(user_id)
      user.update_attributes(is_awesome: true)
    end
  end
end

I also like to give some delay before starting an async job.

class Job
  include SuckerPunch::Job

  def perform(data)
    puts data
  end

  def later(sec, data)
    after(sec) { perform(data) }
  end
end

Job.new.async.perform("asdf")
Job.new.async.later(60, "asdf") # `perform` will be excuted 60 sec. later

So far sucker punch is my best friend when working with Heroku, since I’m a cheapskate, hahah.

Leave a Reply

Your email address will not be published. Required fields are marked *