Sidekiq and Background Jobs for Beginners

rails s
redis-server
sidekiq
mailcatcher
Redis isn’t doing anything

Convert a non-background-job to a background job

  1. create the job. (you can use rails generate job <job_name>, per the ActiveJob docs)
  2. Call the notify user job from the controller, instead of calling the user notifier directly.

Make the job

class SendUserGifJob < ActiveJob::Base
queue_as :default

def perform(*args)
# do da ting
end

end

Make a test

# test/jobs/send_user_gif_job_test.rb

require 'test_helper'

class SendUserGifJobTest < ActiveJob::TestCase
test 'that email is sent' do
SendUserGifJob.perform_async("test@test.com", "hello")
# literally no idea what to assert here...
# assert
end

end

Messed up Sidekiq?

Sidekiq::Queue.all.each(&:clear)
Sidekiq::RetrySet.new.clear
Sidekiq::ScheduledSet.new.clear
Sidekiq::DeadSet.new.clear

Reworked the test and worker

# app/workers/send_gif_to_user_worker.rb

class SendGifToUserWorker
include Sidekiq::Worker

def perform(*args)
# Do something
end
end
# test/workers/send_gif_to_user_worker_test.rb

require 'test_helper'

class SendGifToUserWorkerTest < ActiveJob::TestCase
test 'that email is sent' do
SendGifToUserWorker.perform_async("test@test.com", "hello")
# literally no idea what to assert here...
# assert
end

test 'that job is pushed to queue' do
assert_equal 0, SendGifToUserWorker.jobs.size
SendGifToUserWorker.perform_async("test@test.com", "hello")
assert_equal 1, SendGifToUserWorker.jobs.size
end
end
# test/workers/send_gif_to_user_worker_test.rb:5

def setup
Sidekiq::Worker.clear_all
end

Making Sidekiq do stuff via the Rails Console

# app/workers/send_gif_to_user_worker.rb
class SendGifToUserWorker
include Sidekiq::Worker

def perform(email, thought)
UserNotifier.send_randomness_email(email, thought).deliver_now
end
end
# app/controllers/mailers_controller.rb
class MailersController < ApplicationController

def create
SendGifToUserWorker.perform_async(params[:mailers][:email], params[:mailers][:thought])
flash[:message] = "You did it! Email sent to #{params[:mailers][:email]}"
redirect_to "/sent"
end

def sent
end
end
main:0> SendGifToUserWorker.perform_async("test@test.com", "hello")
=> "08e6a309cf7c46dc0178c53f"
main:0> SendGifToUserWorker.perform_async("test@test.com", "hello")
=> "8b962d28217ae177564f0fd7"
2018-07-27T17:13:55.023Z 10221 TID-ovusw76r0 SendGifToUserWorker JID-08e6a309cf7c46dc0178c53f INFO: start
2018-07-27T17:13:55.023Z 10221 TID-ovusw76r0 SendGifToUserWorker JID-08e6a309cf7c46dc0178c53f INFO: done: 0.0 sec
2018-07-27T17:13:57.521Z 10221 TID-ovusw781o SendGifToUserWorker JID-8b962d28217ae177564f0fd7 INFO: start
2018-07-27T17:13:57.521Z 10221 TID-ovusw781o SendGifToUserWorker JID-8b962d28217ae177564f0fd7 INFO: done: 0.0 sec
Calling Sidekiq jobs from Rails Console

Restart Sidekiq when you make a change to a worker

Watching Redis

Redis-server not showing much
redis-cli showing LOTS
Redis-cli showing useful results

lpush

1532784329.095661 [0 127.0.0.1:53832] lpush queue:default 
{
class:SendGifToUserWorker,
args:[flip,flop],
retry:true,
queue:default,
jid:adfa15f29ed6c09cda7f6973,
created_at:1532784329.095427,
enqueued_at:1532784329.095466
}

hset

1532784332.778327 [0 127.0.0.1:53803] hset MacBook-Pro-6715.local:32134:cc8d1568c5c6:workers ow3kb5tjc 
{
queue:default,
payload:
{
class:SendGifToUserWorker,
args:[flip,flop],
retry:true,
queue:default,
jid:adfa15f29ed6c09cda7f6973,
created_at:1532784329.095427,
enqueued_at:1532784329.095466
},
run_at:1532784329
}

What does/does not occur

SendGifToUserWorker.new.perform(params[:mailers][:email], params[:mailers][:thought])
SendGifToUserWorker.perform_async(params[:mailers][:email], params[:mailers][:thought])
On the left, you can see the POST request come in, redis (top right) and sidekiq (bottom right) responding to said POST request
Same Post request, but the request never gets to Sidekiq or Redis, because I used Worker.new.perform

Conclusion

Resources

--

--

--

Software, rock climbing, books. I love to learn. https://josh.works

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Blazor Dependencies

How to set up your very own local APT repository in Ubuntu

A beginner’s guide for migrating from on-premise to cloud

Optimize our life with systems science

The magic of Recursion and why you should be using it in your code

D.I.Y. load balancer for GKE on the cheap

How to Squeeze Test Driven Development on Legacy Systems

Preparing for a Python skills Test

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Josh Thompson

Josh Thompson

Software, rock climbing, books. I love to learn. https://josh.works

More from Medium

What are RubyGems?

My Thought on Crystal Lang

Ruby on Rails Project: Devhub

ActiveRecord in Ruby simplified