Search code examples
ruby-on-rails-4resquerails-engines

Debugging Resque::Server


We have two Rails applications using Resque and Redis. Resque and Redis are configured identically on both apps, which are both using Rails 4.2 and Resque 1.27.4.

However, the availability of Resque server at the /resque path is best described as "uneven" across the two applications (I'll shorten their real names to "planning" and "staffing" for simplification).

  • Both sites work fine in production (on Heroku). This is particularly interesting because the current production deploy of "planning" has older versions of Rails and Resque than "staffing" - my current project is bringing it up to date.
  • In staging, "staffing" works fine; "planning" returns a 404 error. (Airbrake doesn't log an error.) When jobs are sent to Resque, they seem to run; we just can't see the server to see the queue.
  • In development (my local environment), using rails s, both applications raise a Routing error: No route matches [GET] "/resque", even though the list of routes which follows on the error page includes /resque at top priority:

resque_server_path /resque Resque::Server

Where do I start figuring out what's going right in one place and wrong in another?

Here's the relevant routes.rb line (all of these are the same in both apps):

mount Resque::Server, :at => '/resque', :constraints => RouteConstraint::Admin

lib/tasks/resque.rake:

require 'resque/tasks'

task "resque:setup" => :environment do
  ENV['QUEUE'] = '*'
  Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection }
end

desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"

config/initializers/redis.rb:

# Cloned from staffing

uri = URI.parse(ENV["REDISTOGO_URL"] || "redis://localhost:6379/")
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)

# Tell Resque which redis to use and ensure database connections don't go stale.
Resque.redis = REDIS
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }

# load job classes.
Dir["#{Rails.root}/app/jobs/*.rb"].each { |file| require file }

Resque::Plugins::Status::Hash.expire_in = (24 * 60 * 60) # 24hrs in seconds

# https://github.com/resque/resque/wiki/Failure-Backends
require 'resque/failure/multiple'
require 'resque/failure/airbrake'
require 'resque/failure/redis'
Resque::Failure::Multiple.classes = [Resque::Failure::Redis, Resque::Failure::Airbrake]
Resque::Failure.backend = Resque::Failure::Multiple

config.ru includes this line among non-Resque-related setup:

require 'resque/server'

Where should I look next?

ETA: I tried switching to resque-web by installing that gem, then changing the config/routes.rb like this:

require "resque_web"

Rails.application.routes.draw do
  mount ResqueWeb::Engine, :at => "/resque", :constraints => RouteConstraint::SuperAdmin
end

(Obviously there's more to the file than that, but except for the end that's literally the top of the file.) Same problem remains: visiting /resque raises the error No route matches [GET] "/resque" even though the route clearly exists. Here's the tail of the output of rake routes:

Routes for ResqueWeb::Engine:
            overview GET    /overview(.:format)             resque_web/overview#show
       working_index GET    /working(.:format)              resque_web/working#index
         clear_queue PUT    /queues/:id/clear(.:format)     resque_web/queues#clear {:id=>/[^\/]+/}
              queues GET    /queues(.:format)               resque_web/queues#index
               queue GET    /queues/:id(.:format)           resque_web/queues#show {:id=>/[^\/]+/}
                     DELETE /queues/:id(.:format)           resque_web/queues#destroy {:id=>/[^\/]+/}
             workers GET    /workers(.:format)              resque_web/workers#index
              worker GET    /workers/:id(.:format)          resque_web/workers#show {:id=>/[^\/]+/}
       retry_failure PUT    /failures/:id/retry(.:format)   resque_web/failures#retry
  retry_all_failures PUT    /failures/retry_all(.:format)   resque_web/failures#retry_all
destroy_all_failures DELETE /failures/destroy_all(.:format) resque_web/failures#destroy_all
            failures GET    /failures(.:format)             resque_web/failures#index
             failure GET    /failures/:id(.:format)         resque_web/failures#show
                     DELETE /failures/:id(.:format)         resque_web/failures#destroy
               stats GET    /stats(.:format)                resque_web/stats#index
        stats_resque GET    /stats/resque(.:format)         resque_web/stats#resque
         stats_redis GET    /stats/redis(.:format)          resque_web/stats#redis
          stats_keys GET    /stats/keys(.:format)           resque_web/stats#keys
      keys_statistic GET    /stats/keys/:id(.:format)       resque_web/stats#keys {:id=>/[^\/]+/}
                root GET    /                               resque_web/overview#show

I wonder if there's something about how the engine is mounted? Or, alternately, if something is shadowing the route?


Solution

  • You should investigate the routing constraint defined in the routes.rb file. When constraints fail, they return a 404 Not Found error consistent with the error you’re seeing. What happens when you take out the constraint?