Delayed_job不执行perform方法但清空作业队列

Jam*_*mes 17 ruby-on-rails delayed-job ruby-on-rails-3

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

source 'http://rubygems.org'
gem 'rails', '3.0.0' gem 'delayed_job'
gem 'sqlite3-ruby', :require => 'sqlite3'
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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">
Run Code Online (Sandbox Code Playgroud)

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

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">]
Run Code Online (Sandbox Code Playgroud)

我开始一个工人 script/delayed_job run

队列被清空:

irb(main):006:0> Delayed::Job.all
=> []
Run Code Online (Sandbox Code Playgroud)

但是,没有任何结果,因为puts没有从logger调用中记录任何内容,也没有引发异常.我很感激任何帮助/见解或任何尝试.

Ben*_*ing 12

默认情况下,delayed_job会破坏失败的作业:

因此,第一步是配置初始化程序并停用该行为

Delayed::Worker.destroy_failed_jobs = false  
Run Code Online (Sandbox Code Playgroud)

此外,如果您反序列化失败,那么这是一个即时的作业失败.

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

因此,请尝试在worker.rb的第120行附近添加以下内容

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

这是相当无益的,但至少你会知道这是一个反序列化错误.

我最后只是使用了这份工作.perform()方法构造.更可靠.还要记住将作业定义作为单独的文件放置,以便类加载器在运行时可以找到它(而不是仅仅将类定义内联到模型中).


小智 6

Ben W绝对正确,请确保您有一个文件

"#{Rails.root}/config/initializers/delayed_job_worker.rb"
Run Code Online (Sandbox Code Playgroud)

这定义了工人应该如何表现.工人将悄悄地删除错误.

完成此操作后,您应该能够找到有关错误的更多信息.对于我的例子,我使用的是delayed_job_mongoid,所以这添加了一个"last_error"的条目(我认为你应该在你的mysql表中为delayed_job而不管......)

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

在我的application.rb文件中:

module TextSender
  class Application < Rails::Application
    require "#{Rails.root.to_s}/lib/SendTextJob.rb"
Run Code Online (Sandbox Code Playgroud)

和我的lib文件:

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

然后跑

Delayed::Job.enqueue SendTextJob.new("Work on this text NOW, please?", "5551231234")
Run Code Online (Sandbox Code Playgroud)

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


ste*_*tef 0

我刚刚将你的课程复制到 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
Run Code Online (Sandbox Code Playgroud)

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

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

File.open("testing.txt", 'w') {|f| f.write("hello") }
Run Code Online (Sandbox Code Playgroud)

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