2013-04-03 34 views
12

我有这个Sidekiq工人:Sidekiq如何将参数传递给执行方法?

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 

我通过散列到perform_async方法,但我认为,转移到perform方法的参数是相同的类型并不像那些传递给perform_async。我试图用户logger.infop来调试我的问题,但没有得到输出...

问题是作业被添加到电子邮件队列,但从来没有得到处理。我甚至试图提高在perform方法异常(在方法的第一行),但没有要么输出...

我知道作为一个事实,即以下工作的工人:

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 

所以问题在于散列参数(选项)。请问我做错了什么?

+0

你确定你已经开始sidekiq工人?在另一个终端中运行'bundle exec sidekiq'。另外,你正在使用一个名为'email'的队列,所以你需要运行'sidekiq -q email'。 –

+0

是的,这是问题所在。我需要用电子邮件队列启动sidekiq。所以我在sidekiq.yml配置文件中添加了一个队列列表,解决了这个问题。你可以添加你的评论作为答案,以便我可以接受它吗? –

回答

1

您正在使用一个名为email的队列,因此您需要运行sidekiq -q电子邮件。

19

Sidekiq documentation

传递给perform_async必须由简单 JSON数据类型的参数:字符串,整数,浮点数,布尔值,null,数组和散列。 Sidekiq客户端API使用JSON.dump将数据发送到Redis。Sidekiq服务器从Redis获取JSON数据并将JSON.load用于 将数据转换回Ruby类型以传递给执行方法。 不要将符号或复杂的Ruby对象(如Date或Time!)作为 ,否则这些对象无法在转储/装载往返中正常运行。

你可以看到这个在控制台上:

> 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 

它看起来像你正在使用的符号,为您options哈希键。如果你切换到字符串键,它应该工作。

+0

另请注意,哈希可能有问题。将这些作为JSON传递给我解决了一个神秘的“错误数量的参数”错误。 – ericpeters0n

+0

我有类似的东西。工作人员第一次运行时,我得到了一个我的代码引发的异常,下一次重试时出现错误的参数错误。 – holaSenor