ruby-on-railsruby-on-rails-4rakeresqueuninitialized-constant

Unbelievable issue with resque - uninitialized constant MyWorker


I'm running into an extremely strange bug with Resque.

And here is the strangest thing in the world : sometimes (yeah, SOMETIMES), resque can't find the class MediaAnalyzer.

Why sometimes ? Because sometimes job is processed without any problem at all. Yet some other times I got uninitialized constant MediaAnalyzer. Even stranger, if I retry the job via resque-web, after a couple of times, the worker is finally found and performed...

All workers are started in the same way with the same command (except for PID and log paths) :

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

Note : even when started manually on the console in foreground mode I keep getting the same bug.

I even tried to manually load the class via the resque:setup task :

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

This cause no error, I can after this require use everything in the class, I can output stuff so this rake task is actually called... but resque keeps failing at loading this class later.

The biggest difficulty is that this bug is really genuinely random !

Here is a pastebin of the exception backtrace : http://pastebin.com/jy5UakB8

Tried with resque 2.0, same issue.

If you know what is happening you're a genius !


Solution

  • Okay guys, I fixed the issue. And it was a really stupid issue.

    I got 2 staging for this application, beta and production. The actual issue was that the MediaAnalyzer is not anymore present in the beta application... And my workers from beta were performing the jobs instead of the workers from the production application.

    I didn't pay enough attention to the exception log, it was saying that myapp_beta/ in the backtrace.

    The issue is simple to resolve, I just had to namespace the redis/resque with :

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

    And add this environment variable to the worker command :

    RESQUE_NAMESPACE=resque:myapp_production 
    

    (or RESQUE_NAMESPACE=resque:myapp_beta for beta obviously)

    That's why it was random, it was depending on which worker was catching the job, one from the beta or one from the production.