【问题标题】:Why won't delayed job process enqueued job?为什么不会延迟作业进程排队作业?
【发布时间】:2015-02-18 07:15:00
【问题描述】:

我已经尽可能地精简了我的例子。在我的应用程序中,我创建了一个虚拟类并尝试将调用方法排入队列。这可以很好地添加到数据库中,并且延迟作业在后台运行,它会拾取它并将其更新为锁定。但它实际上并没有完成运行工作。它只是停留在锁定状态。

pry(main)> class DummyClass
pry(main)*   def self.call
pry(main)*     puts 'will this ever work?'
pry(main)*   end
pry(main)* end
=> :call

pry(main)> DummyClass.delay.call

(0.2ms)  BEGIN
SQL (0.3ms)  INSERT INTO `delayed_jobs` (`created_at`, `handler`, `queue`, `run_at`, `updated_at`) VALUES ('2014-12-19 12:11:40.006107', '--- !ruby/object:Delayed::PerformableMethod\nobject: !ruby/class \'DummyClass\'\nmethod_name: :call\nargs: []\n', 'default', '2014-12-19 12:11:40.005811', '2014-12-19 12:11:40.006107')
(16.2ms)  COMMIT

=> #<Delayed::Backend::ActiveRecord::Job:0x007fd0fdec0e20
 id: 22,
 priority: 0,
 attempts: 0,
 handler: "--- !ruby/object:Delayed::PerformableMethod\nobject: !ruby/class 'DummyClass'\nmethod_name: :call\nargs: []\n",
 last_error: nil,
 run_at: Fri, 19 Dec 2014 14:11:40 CAT +02:00,
 locked_at: nil,
 failed_at: nil,
 locked_by: nil,
 queue: "default",
 created_at: Fri, 19 Dec 2014 14:11:40 CAT +02:00,
 updated_at: Fri, 19 Dec 2014 14:11:40 CAT +02:00>

在此处锁定任务

  SQL (0.8ms)  UPDATE `delayed_jobs` SET `delayed_jobs`.`locked_at` = '2014-12-19 12:17:20.031925', `delayed_jobs`.`locked_by` = 'delayed_job host:Ryan-Mes-MacBook-Pro-2.local pid:60080' WHERE ((run_at <= '2014-12-19 12:17:20.031003' AND (locked_at IS NULL OR locked_at < '2014-12-19 12:12:20.031154') OR locked_by = 'delayed_job host:Ryan-Mes-MacBook-Pro-2.local pid:60080') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1

然后它就挂了。我不明白为什么这么简单的任务不起作用。

请注意,这个 pry 控制台正在我现有的 rails 应用程序上运行。可能是应用程序配置问题,但我一直没找到。

有什么想法吗?我可以尝试提供更多信息,但我认为这就是一切。

我使用的实际代码如下

module Events
  class ForwardRequestToPulse
    def self.call
      puts 'will this ever work'
    end
  end
end

class MyTestController < ApplicationController
  def index
    Events::ForwardRequestToPulse.delay.call
  end
end

记录被添加到delayed_jobs 表中查找。当我运行bin/delayed_job run 时,记录被锁定但未处理。

下面是锁定记录的图像

【问题讨论】:

  • 澄清一下,后台处理开始了吗?
  • 是的。我尝试了 bin/delayed_job start 的变体来获取工作:工作和其他。一切似乎都开始了,但还没有结束。数据库只是挂起,第一个作业排队处于锁定状态。
  • 好的。据我所知,延迟作业处理开始时它会启动一个新进程。这个新进程可能无法访问 Pry 中定义的 DummyClass。您是否尝试过在模型中调用某些方法?
  • 是的,我有。实际上,我有一项服务需要使用延迟作业进行排队。延迟部分工作正常。它将它推送到队列中,但是当它尝试处理队列时它只是挂起。
  • 日志说什么?尝试“bin/delayed_job run”,这将在不分叉进程的情况下运行作业,看看是否发生任何错误。

标签: ruby-on-rails ruby-on-rails-4 delayed-job


【解决方案1】:

我对 Sidekiq 更熟悉,但我认为问题在于您正在定义一个要在 rails 控制台中运行的类,并且工作人员在单独的进程中运行。工作人员不知道 DummyClass 并且无法执行作业。我推荐:

  1. 让这个类成为 Rails 模型(Dummy 等)
  2. 重启延迟的作业
  3. 将记录插入到delayed_job表中
  4. 检查锁定状态

【讨论】:

  • 我同意@eabraham - 工作人员必须已经可以访问实现(类定义),因为它序列化了要通过名称和值调用的作业,稍后必须重新构建它们
  • 我明白你在说什么。我认为这个例子会简化我的解释。在我的 rails 应用程序中使用服务对象时,我仍然遇到同样的问题(这是我原来的问题)。如果我的服务对象显示相同的行为,有关错误可能是什么的任何建议。 Delayed_job 似乎将记录锁定在数据库中,然后什么也不做。至少不会失败吗?
  • 你能发布由DelayedJob执行的实际代码,而不是虚拟代码吗?如果没有具体看到您正在运行的内容,我很难提供帮助。
  • @eabraham 我已在问题中添加了其他信息。同样的事情正在发生。有任何想法吗?谢谢。
  • 查看 gem 延迟作业 Delayed::Backend::ActiveRecord::Job.reserve_with_scope 似乎延迟作业在更新锁定日期后找不到工作。用于更新记录的日期时间是 2015-01-05 11:13:45 +0200 但是存储在数据库中的值是 2015-01-05 09:13:45 我猜这是问题所在。不是 100% 确定如何解决它。这必须是有关时区或类似内容的应用程序设置。会继续找。想法?
【解决方案2】:

在 gem 中摆弄之后,我将问题缩小到 delay_job 没有正确查找锁定记录。它在locked_at 的过滤器中包含毫秒。 mySql 存储没有毫秒的日期时间,因此没有任何内容被拾取。在对 github delayed_job_active_record 中的 gem 进行了更多研究之后(我认为问题出在我身上!)我发现了这个 fix。这解决了我的问题。

发生这种情况的原因是我在此修复之前引用了最新的 gem 4.0.2!只是我的运气。

因此,如果您使用的是 4.0.2 ... 只需升级它就会消失。

【讨论】:

    猜你喜欢
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多