resque令人难以置信的问题 - 未初始化的常量MyWorker

时间:2014-04-18 09:16:05

标签: ruby-on-rails ruby-on-rails-4 rake resque uninitialized-constant

我遇到了Resque的一个非常奇怪的错误。

  • 我有5名工人在跑,有一个队列,等待工作。
  • 我有一种Resque工作者:MediaAnalyzer

这是世界上最奇怪的事情:有时(是的,有时候),resque找不到类MediaAnalyzer。

为什么有时候?因为有时处理工作没有任何问题。然而有些时候我得到uninitialized constant MediaAnalyzer。更奇怪的是,如果我通过resque-web重试这项工作,经过几次,工人终于找到并执行......

所有worker都以相同的方式使用相同的命令启动(PID和日志路径除外):

su -c "cd /myapp/current; bundle exec rake environment resque:work RAILS_ENV=production QUEUES=* BACKGROUND=yes PIDFILE=/myapp/current/tmp/pids/resque_worker.1.pid 2>&1 >> /myapp/shared/log/resque_worker.1.log" - rails

注意:即使在前台模式下在控制台上手动启动,我也会遇到同样的错误。

我甚至尝试通过resque:setup task:

手动加载类
task "resque:setup" => :environment do
  require Rails.root.join("app/workers/media_analyzer").to_s
end

这导致没有错误,我可以在require之后使用类中的所有东西,我可以输出东西,所以这个rake任务实际上被调用了......但resque在以后加载这个类时仍然失败。

最大的困难是这个bug确实是随机

以下是异常回溯的代码:http://pastebin.com/jy5UakB8

尝试使用resque 2.0,同样的问题。

如果你知道发生了什么,那你就是天才!

3 个答案:

答案 0 :(得分:1)

您遇到的随机问题很容易由Rails / Ruby自动加载引起。加载的订单文件有时是不可能的。结合使用错误的文件名或将其放入错误的目录可能会导致此问题。

如果在引用类本身之前明确要求定义了类的文件,则不会获得异常。如果您引用第一个Rails,请尝试在加载路径中查找相应的文件。如果它找不到它,它就会升起。

请仔细检查您的文件名,并查看$LOAD_PATH变量。应该包括app/workers

一个简单的测试就是运行rails console并只需访问MediaAnalyzer

答案 1 :(得分:1)

好的,我解决了这个问题。这是一个非常愚蠢的问题。

我为此应用程序,测试版和制作版进行了2次分期。实际问题是,BetaA应用程序中不再存在MediaAnalyzer ......我的beta工作人员正在执行作业而不是生产应用程序中的工作人员。

我没有对异常日志给予足够的重视,它在回溯中说myapp_beta/

这个问题很容易解决,我只需用redis / resque命名:

 Resque.redis.namespace = "resque:myapp_#{Rails.env}"

并将此环境变量添加到worker命令:

RESQUE_NAMESPACE=resque:myapp_production 

(或显然是RESQUE_NAMESPACE=resque:myapp_beta

这就是为什么它是随机的,这取决于哪个工作者正在接受这个工作,一个来自测试版,另一个来自制作中。

答案 2 :(得分:1)

如果您正在使用ActiveJob并注意到这一点,我发现解决问题的方法就是重启Redis服务器。我不确定为什么这个工作还没有完成,但是一切都在我做完之后就开始工作并杀死了所有工人。