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?
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.