【问题标题】:Delayed_job not executing the perform method but emptying the job queueDelayed_job 不执行 perform 方法但清空作业队列
【发布时间】:2011-05-31 22:31:22
【问题描述】:

我有一个新的 rails 3 应用,这是我的 Gemfile:

source 'http://rubygems.org'
gem 'rails', '3.0.0' gem 'delayed_job'
gem 'sqlite3-ruby', :require => 'sqlite3'

这是代表我要排队的作业的类:

class Me < Struct.new(:something)
   def perform
     puts "Hello from me"
     logger.info "Hello from me"
     logger.debug "Hello from me"
     raise Exception.new   
   end
end

从没有工人运行的控制台:

irb(main):002:0> Delayed::Job.enqueue Me.new(1)
=> #<Delayed::Backend::ActiveRecord::Job id: 7, priority: 0, attempts: 0, handler: "--- !ruby/struct:Me \nsomething: 1\n", last_error: nil, run_at: "2010-12-29 07:24:11", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2010-12-29 07:24:11", updated_at: "2010-12-29 07:24:11">

就像我提到的:没有工人在运行:

irb(main):003:0> Delayed::Job.all
=> [#<Delayed::Backend::ActiveRecord::Job id: 7, priority: 0, attempts: 0, handler: "--- !ruby/struct:Me \nsomething: 1\n", last_error: nil, run_at: "2010-12-29 07:24:11", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2010-12-29 07:24:11", updated_at: "2010-12-29 07:24:11">]

我用script/delayed_job run开始一个工人

队列被清空:

irb(main):006:0> Delayed::Job.all
=> []

但是,puts 不会导致任何事情发生,logger 调用不会记录任何内容,并且不会引发异常。我将不胜感激任何帮助/见解或任何尝试。

【问题讨论】:

  • 我遇到了完全相同的问题。你有没有解决过这个问题?

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


【解决方案1】:

默认情况下,delayed_job 会销毁失败的作业:

所以第一步是配置初始化程序并停用该行为

Delayed::Worker.destroy_failed_jobs = false  

此外,如果您遇到反序列化失败,那么这就是即时作业失败。

这会触发作业删除(如果您尚未删除它)。

所以尝试在 worker.rb 的第 120 行附近添加以下内容

rescue DeserializationError => error
  say "DeserializationError: #{error.message}"
  job.last_error = "{#{error.message}\n#{error.backtrace.join('\n')}"
  failed(job)

这没什么用,但至少你会知道这是一个反序列化错误。

我最终只使用了 w 的工作。 perform() 方法构造。可靠得多。还要记住将你的作业定义作为一个单独的文件,这样类加载器可以在它运行时找到它(而不是仅仅将类定义内联到你的模型中的某个地方)。

【讨论】:

    【解决方案2】:

    Ben W 是绝对正确的,确保你有一个文件

    "#{Rails.root}/config/initializers/delayed_job_worker.rb"
    

    这定义了工人的行为方式。否则,工作人员将悄悄地删除错误。

    执行此操作后,您应该能够了解有关您的错误的更多信息。对于我的例子,我使用了delayed_job_mongoid,所以这添加了一个“last_error”条目(我认为你应该在你的mysql表中为delayed_job添加一个条目......)

    正如 Ben W 总结的那样,您需要确保应用程序(或工作人员)知道您正在创建的对象。我的问题是我在 Rails 控制台中测试一个类对象。工人不知道这个类,所以它吐了。

    在我的 application.rb 文件中:

    module TextSender
      class Application < Rails::Application
        require "#{Rails.root.to_s}/lib/SendTextJob.rb"
    

    还有我的 lib 文件:

    class SendTextJob < Struct.new(:text, :number)
      def perform
        Rails.logger.info "Sending #{text} to #{number}"
        puts "Successfully sent text"
      end
    end
    

    然后运行

    Delayed::Job.enqueue SendTextJob.new("Work on this text NOW, please?", "5551231234")
    

    在我的 log/development.log 文件中确认这是成功的。我还在这个 perform 方法中测试了创建和对象(用户对象或任何你可能拥有的模型),并且它有效。

    【讨论】:

      【解决方案3】:

      我遇到了这个问题,我发现这是因为在 Rails 3 中lib/ 目录中的文件没有自动加载。为了诊断,我补充说:

      # application.rb
      Delayed::Worker.destroy_failed_jobs = false
      

      正如 Ben W 所提到的。这告诉了我发生了什么,因为我可以检查 last_error

      所以为了解决自动加载问题,我在 SO 上找到了几个答案,但要点是添加:

      # application.rb
      
      # Custom directories with classes and modules you want to be autoloadable.
      # config.autoload_paths += %W(#{config.root}/extras)
      config.autoload_paths += %W(#{config.root}/lib)
      config.autoload_paths += Dir["#{config.root}/lib/**/"]
      

      http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/提供。

      我很想知道如何在不为 lib 目录打开自动加载的情况下解决这个问题。有什么想法吗?

      【讨论】:

        【解决方案4】:

        我刚刚将你的课程复制到 irb 并尝试做Me.new.perform

        Hello from me
        NameError: undefined local variable or method `logger' for #<struct Me something=nil>
        from (irb):6:in `perform'
        from (irb):14
        

        您的班级是否可以访问“记录器”?

        您可以尝试做其他事情,例如打开和写入文件?

        File.open("testing.txt", 'w') {|f| f.write("hello") }
        

        请记住,延迟作业工作者的“puts”命令将输出到 标准输出,因此您可能永远不会看到这一点。如果你想做任何日志记录,我认为你必须在你的 perform 方法中创建一个新的 Logger 实例才能这样做。

        【讨论】:

        • 我尝试删除记录器调用并按照您的描述写入文件。我仍然看到相同的行为 - 作业从队列中删除,但文件没有被写入。
        【解决方案5】:

        你运行的是什么版本的delayed_job?

        对于 Rails 3.0 及更高版本,您需要位于 https://github.com/collectiveidea/delayed_job 的 2.1 分支。

        【讨论】:

        • 是的,它是我认为是 2.1 的主分支
        【解决方案6】:

        检查日志,您应该会看到有关 DelayedJob 消息,至少启动了哪个作业以及它的退出状态是什么

        在终端中,启动:

        tail -f log/development.log
        

        然后从 Rails 控制台重试以检查执行简单的 ActiveRecord 查询会发生什么,然后使用 DelayedJob。您可以阅读其他终端上记录的内容

        干杯, A.

        【讨论】:

          猜你喜欢
          • 2011-06-21
          • 2019-11-28
          • 1970-01-01
          • 2016-09-01
          • 2012-03-17
          • 1970-01-01
          • 1970-01-01
          • 2012-01-26
          • 2016-12-30
          相关资源
          最近更新 更多