2017-02-13 38 views
1

有沒有辦法從Sidekiq作業中錯誤地告訴Sidekiq「這個錯誤是致命的,不可恢復的,不要重試,直接發送到死的作業隊列」?Sidekiq瞬態vs致命錯誤

查看Sidekiq Error Handling文檔,它似乎將所有錯誤解釋爲暫時性的,並且將重試作業(如果重試已啓用),而不考慮錯誤類型。

+0

也許在回答[這](https://github.com/mperham/sidekiq/issues/2072)問題可以幫助你? –

+0

@JeroenHeier關於你鏈接的問題的意見之一正是我想要的:https://github.com/mperham/sidekiq/issues/2072#issuecomment-160832087 – mtulio

+0

@JeroenHeier你會介意發佈它是一個答案,所以我可以將其標記爲已接受? – mtulio

回答

0

如果在GitHub上發現問題的解決方案。在那篇文章中,他們建議編寫一個自定義中間件來處理您想要阻止重試的異常。這是一個基本的例子:

def call(worker, msg, queue) 
    begin 
    yield 
    rescue ActiveRecord::RecordNotFound => e 
    msg['retry'] = false 
    raise 
    end 
end 

您可以延長你得到:

def call(worker, msg, queue) 
    begin 
    yield 
    rescue ActiveRecord::RecordNotFound => e 
    msg['retry'] = false 
    raise 
    rescue Exception => e 
    if worker.respond_to?(:handle_error) 
     worker.handle_error(e) 
    else 
     raise 
    end 
    end 
end 
3

你應該拯救那些特定的錯誤,而不是重新提高它們。

def perform 
    call_something 
rescue CustomException 
    nil 
end 

編輯:

好吧,如果你想故意將消息發送到DLQ/DJQ,你需要做的是做什麼#send_to_morgue做的方法。我敢肯定,邁克·佩勒姆將要來到這裏並大聲喝斥我要表明這一點,但...

def send_to_morgue(msg) 
     Sidekiq.logger.info { "Adding dead #{msg['class']} job #{msg['jid']}" } 
     payload = Sidekiq.dump_json(msg) 
     now = Time.now.to_f 
     Sidekiq.redis do |conn| 
     conn.multi do 
      conn.zadd('dead', now, payload) 
      conn.zremrangebyscore('dead', '-inf', now - DeadSet.timeout) 
      conn.zremrangebyrank('dead', 0, -DeadSet.max_jobs) 
     end 
     end 
    end 

唯一的區別你必須挖成什麼msg看起來像進入那個方法,但我懷疑這是通常在解析之前碰到中間件的東西。

+0

'nil'是多餘的:) – mudasobwa

+0

@mudasobwa同意但我把它放在那裏,所以它是明確的 – Anthony

+0

不幸的是,這不會發送消息到Dead Job Queue,這是我想要的「致命」錯誤的工作流程的重要部分。 – mtulio