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文件中确认这是成功的.我还在这个执行方法中测试了创建和对象(用户对象或你可能拥有的任何模型),并且它有效.
我刚刚将你的课程复制到 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 实例才能执行此操作。