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_get
和 const_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
我以前尝试过使用 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_get
和 const_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