Resque 任务总是失败 - 未初始化的作业常量?

Resque tasks always fail - uninitialized job constants?

我以前尝试过使用 Resque,但遇到了彻头彻尾的失败。我再次访问它,结果相同...

resque.rake:

require "resque/tasks"

task "resque:setup" => :environment

test.rb:

require 'resque'

class FileWorker
  @queue = :save_to_file

  def self.perform(str)
    File.open('./' + Time.now.to_s + '.txt', 'w+') do |f|
      f << "test 123"
    end
  end
end

Resque.enqueue(FileWorker, "12345567".split('').shuffle.join)

Gemfile:

gem 'resque'
gem 'rake'

似乎 运行ning test.rb 自己成功地排队了作业:

但是,在同一文件夹中 运行ning rake resque:work QUEUE='*' 会导致警告,

WARNING: This way of doing signal handling is now deprecated. Please see http://hone.heroku.com/resque/2012/08/21/resque-signals.html for more info.

以及添加到 "failed" 队列的任务,原因如下:"exception":"NameError","error":"uninitialized constant FileWorker"

如何让它工作?看起来很明显,但是有很多关于 Resque 的教程跨越了很多年 - 有些已经过时了,none 解释了如何 运行 workers 所以他们不会失败。

提前致谢。

当您使用 Resque 对任务进行排队时,Redis 上存储的只是作业的名称 class(作为字符串)以及 [=52= 中的参数(同样作为字符串) ] 对象。

当工作人员随后尝试执行任务时,它需要能够创建作业的实例 class。它通过使用 const_getconst_missing 来实现。这是您看到的错误发生的地方,因为工作人员没有可用的 FileWorker 定义。

错误与您尝试在 irb 中获取未知常量相同:

> Object.const_missing "FileWorker"
NameError: uninitialized constant FileWorker

解决方案是确保 FileWorker 的定义对您的工作人员可用。最简单的方法是只需要 Rakefile(或 resque.rake)的 test.rb。在您的代码中,这将涉及向队列添加另一个任务,因此您可能希望将 FileWorker 代码移动到它自己的文件中,rake 文件和代码排队作业都需要它。

test.rb:

require 'resque'
require './file_worker'

Resque.enqueue(FileWorker, "12345567".split('').shuffle.join)

Rakefile(注意 :environment 任务只有在您使用 Rails 时才有意义,否则会出错):

require "resque/tasks"
require "./file_worker"

file_worker.rb:

class FileWorker
  @queue = :save_to_file

  def self.perform(str)
    File.open('./' + Time.now.to_s + '.txt', 'w+') do |f|
      f << "test 123"
    end
  end
end

现在工作人员将能够创建 FileWorker 的实例来完成任务。


避免信号警告的方法在page linked to in the message中给出。只需在调用 rake 时设置环境变量 TERM_CHILD:

$ rake resque:work QUEUE='*' TERM_CHILD=1