【问题标题】:Programmatic access to the Resque failed-job queue以编程方式访问 Resque 失败作业队列
【发布时间】:2013-01-13 17:26:25
【问题描述】:

如何编写代码以通过 Resque 失败队列并有选择地删除作业?现在,我在那里遇到了一些重要的失败,散布在重复运行的失控工作的数千次失败之间。我想删除失控作业生成的那些。我熟悉的唯一 API 是用于排队作业。 (我会继续 RTFMing,但我有点着急。)

【问题讨论】:

  • 可能不是您想听到的,但直接访问 Redis 并以这种方式更改数据可能是最好的选择。

标签: ruby resque


【解决方案1】:

您可以按照您的要求手动修改失败队列,但最好编写一个自定义失败处理程序,以便在作业失败时删除/重新入队。

您可以找到基本故障后端 here 以及将失败作业记录到 Hoptoad 异常跟踪服务 here 的实现。

例如:

module Resque
  module Failure
    class RemoveRunaways < Base
      def save
        i=0
        while job = Resque::Failure.all(i)
          # Selectively remove all MyRunawayJobs from failure queue whenever they fail
          if job.fetch('payload').fetch('class') == 'MyRunawayJob'
            remove(i) 
          else
            i = i + 1
          end
        end
      end
    end
  end
end

编辑:忘了提到如何指定这个后端来处理失败。

在您的 Resque 初始化程序中(例如:config/initializers/resque.rb):

# Use Resque Multi failure handler: standard handler and your custom handler
Resque::Failure::Multiple.classes = [Resque::Failure::Redis, Resque::Failure::RemoveRunaways]
Resque::Failure.backend = Resque::Failure::Multiple

【讨论】:

    【解决方案2】:

    我需要这样做:

    # loop over all failure indices, instantiating as needed  
    (Resque::Failure.count-1).downto(0).each do |error_index_number|     
    
      failure = Resque::Failure.all(error_index_number)
    
      # here :failure is the hash that has all the data about the failed job, perform any check you need here      
    
      if failure["error"][/regex_identifying_runaway_job/].present?        
        Resque::Failure.remove(error_index_number)
        # or
        # Resque::Failure.requeue(error_index_number)
      end
    

    正如@Winfield 所说,查看Resque's failure backend 很有用。

    【讨论】:

      【解决方案3】:

      用bool函数删除示例

      我使用了高阶函数方法,它评估删除失败

          def remove_failures(should_remove_failure_func)
            (Resque::Failure.count-1).downto(0).each do |i|
              failure = Resque::Failure.all(i)
              Resque::Failure.remove(i) if should_remove_failure_func.call(failure)
            end
          end
      
          def remove_failed_validation_jobs
            has_failed_for_validation_reason = -> (failure) do
              failure["error"] == "Validation failed: Example has already been taken"
            end
            remove_failures(has_failed_for_validation_reason)
          end
      

      【讨论】:

      • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
      猜你喜欢
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      • 2012-08-22
      • 2023-01-10
      • 2016-11-05
      • 2015-03-24
      相关资源
      最近更新 更多