使用 Resque-scheduler 和 redis 时,在上述延迟时间过后,延迟作业未进入主作业队列

Mah*_*sta 5 ruby-on-rails delayed-job redis resque-scheduler rails-activejob

我需要执行一项工作,其中每次创建订单时都会将其分配给供应商,如果供应商不接受订单并在指定时间内更新状态,则订单将自动拒绝并将状态更新为拒绝。我面临的问题是,作业会转到延迟队列,如 resque Web 视图中所示,但在延迟失效的指定时间后不会移动到主队列

这是我的工作。

  class AutoRejectionJob < ActiveJob::Base
    queue_as :auto_rejection_queue

   def perform(*args) 
    assignment_id = args[0]
    order_assignment = Estamps::Assignment.find(assignment_id)
    if order_assignment.status_id == 1 || order_assignment.status_id == nil
      order_assignment.status_id = 3
      order_assignment.save!
    end
   end
  end         
Run Code Online (Sandbox Code Playgroud)

在我的作业模型中:

class Estamps::Assignment < ActiveRecord::Base
 after_create :enqueue_check_status 

def enqueue_check_status #  
  AutoRejectionJob.set(wait: 2.minutes).perform_later(self.id)
end    
end
Run Code Online (Sandbox Code Playgroud)

这里,一旦创建了分配记录,其状态通常在创建时保持为“已分配”。现在,从创建之日起,如果用户未在指定时间内更新状态,则作业必须自动将状态更新为“已拒绝”。

我也尝试过这个方法。

def enqueue_check_status 
  Resque.enqueue_at_with_queue('auto_rejection_queue', 2.minutes.from_now, 
   AutoRejectionJob, assignment_id: self.id)  
end
Run Code Online (Sandbox Code Playgroud)

它们都将作业发送到resque延迟队列,但不将作业带到主队列执行。

自动拒绝作业在延迟作业列表中排队

此外,当我单击延迟作业的所有计划链接时,作业的时间戳显示没有列出要计划的作业

延迟列表中第一个作业的所有时间表

我被这个问题困扰了将近两周。请帮忙!如果需要更多信息,请告诉我。和这个人度过了一段艰难的时光。

Ash*_*Ash 4

我已经解决了这个问题。

基本上,让工作人员运行本身不足以处理延迟的作业。您必须运行一个特殊的 rake 任务:

$ PIDFILE=./resque-scheduler.pid BACKGROUND=yes \
    rake resque:scheduler
Run Code Online (Sandbox Code Playgroud)

resque:scheduler rake 任务检查计划作业和延迟作业(默认情况下每 5 秒一次),并将它们移至您的工作线程进行处理。您可以在官方resque-scheduler gem readme上阅读有关如何配置和设置 resque:scheduler rake 任务及其设置的更多信息。

就我而言,我使用capistrano-resque gem来部署和管理工作线程(当 capistrano 部署新版本时重新启动它们),方法是将以下行添加到 deploy.rb 文件中:

after "deploy:restart", "resque:restart"
Run Code Online (Sandbox Code Playgroud)

虽然这加载了我的工作人员(并按应有的方式重新启动了它们),但您需要添加额外的行(到deploy.rb):

after 'passenger:restart', 'resque:scheduler:restart'
Run Code Online (Sandbox Code Playgroud)

让 capistrano 为您运行 resque:scheduler 任务。

在我这样做之后,一切都工作得非常完美(并且实际上回顾性地加载了应该已处理但尚未处理的延迟作业)。

但是,如前所述,如果您确实遇到问题,请确保您的 rake resque:scheduler 任务可以访问环境变量 - 否则它将无法工作。