I have this Sidekiq worker:
class DealNoteWorker
include Sidekiq::Worker
sidekiq_options queue: :email
def perform(options = {})
if options[:type] == "deal_watch_mailer"
deal_watchers = DealWatcher.where("deal_id = ?", options[:deal_id])
deal_note = DealNote.find(options[:deal_note_id])
current_user = User.find(options[:current_user_id])
deal_watchers.each do |deal_watcher|
unless deal_watcher.user_id == options[:current_user_id]
# Tell the DealWatchMailer to send emails to ALL watchers advising of change to deal
if deal_watcher.user.active
DealWatchMailer.deal_watch_email(deal_watcher, nil, deal_note, current_user, options[:url]).deliver
end
end
end
elsif options[:type] == "deal_note_mailer"
options[:user_ids].each do |id|
if DealWatcher.where("deal_id = ? and user_id =?", options[:deal_id], id).count == 0
deal_note = Deal.find(options[:deal_note_id])
user = User.find_by_id(id)
DealNoteMailer.deal_note_email(deal_note, user, options[:url]).deliver
end
end
end
end
end
I pass a hash to the perform_async
method, but I think that the parameters transfered to the perform
method are not of the same type as the ones passed to perform_async
. I tried to user logger.info
and p
to debug my issue but nothing gets outputted...
The issue is that the job is added to the email queue but never gets processed. I even tried to raise an exception in the perform
method (on the first line of the method) but nothing was outputted either...
I know as a fact that the following worker works:
class DealNoteWorker
include Sidekiq::Worker
def perform(deal_id, deal_note_id, current_user_id, url)
deal_watchers = DealWatcher.where("deal_id = ?", deal_id)
deal_note = DealNote.find(deal_note_id)
current_user = User.find(current_user_id)
deal_watchers.each do |deal_watcher|
unless deal_watcher.user_id == current_user_id
# Tell the DealWatchMailer to send emails to ALL watchers advising of change to deal
if deal_watcher.user.active
DealWatchMailer.deal_watch_email(deal_watcher, nil, deal_note, current_user, url).deliver
end
end
end
end
end
So the problem lies in the hash parameter (options). What am I doing wrong please?
Sidekiq server process pulls jobs from the queue in Redis and processes them. Like your web processes, Sidekiq boots Rails so your jobs and workers have the full Rails API, including Active Record, available for use. The server will instantiate the worker and call perform with the given arguments.
Simple, efficient background processing for Ruby. Sidekiq uses threads to handle many jobs at the same time in the same process. It does not require Rails but will integrate tightly with Rails to make background processing dead simple.
It works the same way as the scheduled queue; it contains jobs that have to be executed at a given time in the future. The main difference is that in retries queue, jobs are added by the Sidekiq, and the time when the job should be executed is calculated based on the retries counter.
Sidekiq is usually the background job processor of choice for Ruby-on-Rails, and uses Redis as a data store for the job queues.
From the Sidekiq documentation:
The arguments you pass to perform_async must be composed of simple JSON datatypes: string, integer, float, boolean, null, array and hash. The Sidekiq client API uses JSON.dump to send the data to Redis. The Sidekiq server pulls that JSON data from Redis and uses JSON.load to convert the data back into Ruby types to pass to your perform method. Don't pass symbols or complex Ruby objects (like Date or Time!) as those will not survive the dump/load round trip correctly.
You can see this on the console:
> options = { :a => 'b' }
> how_sidekiq_stores_the_options = JSON.dump(options)
> how_sidekiq_loads_the_options = JSON.load(how_sidekiq_stores_the_options)
> how_sidekiq_stores_the_options == how_sidekiq_loads_the_options
false
It looks like you are using symbols as the keys for your options
hash. If you switch to string keys, it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With