cache_sweeper method not found - ruby-on-rails-3

I'm deploying my Rails 3 application to a Tomcat 6 server. I've been using warble to package my project up into a war file and so far have not had any troubles, until now. I just added a cache_sweeper to my application. When I tried hitting the application, I received the standard 500 error page.
Looking at my logs, I saw this:
org.jruby.rack.RackInitializationException: undefined method `cache_sweeper' for ApplicationController:Class
It can't find the cache_sweeper method? Isn't that part of Rails?
This doesn't happen while in development mode, though in development I'm using MRI ruby and using the rails server instead.
Anyone have any ideas?!
Full error:
SEVERE: Application Error
org.jruby.rack.RackInitializationException: undefined method `cache_sweeper' for ApplicationController:Class
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/app/controllers/application_controller.rb:239:in `require'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in `require'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:227:in `load_dependency'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in `require'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:346:in `require_or_load'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:491:in `load_missing_constant'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:183:in `const_missing'
from C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/gems/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:181:in `each'
... 39 levels...
from file:/C:/bin/apache-tomcat-6.0.29/webapps/rails3app/WEB-INF/lib/jruby-rack-1.0.3.jar!/vendor/rack-1.2.1/rack/builder.rb:46:in `initialize'
from <script>:2:in `new'
from <script>:2
at org.jruby.rack.DefaultRackApplicationFactory$4.init(DefaultRackApplicationFactory.java:184)
at org.jruby.rack.DefaultRackApplicationFactory.getApplication(DefaultRackApplicationFactory.java:59)
at org.jruby.rack.PoolingRackApplicationFactory.getApplication(PoolingRackApplicationFactory.java:94)
at org.jruby.rack.servlet.DefaultServletDispatcher.process(DefaultServletDispatcher.java:36)
at org.jruby.rack.RackFilter.doFilter(RackFilter.java:59)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:861)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1584)
at java.lang.Thread.run(Thread.java:619)

For whatever reason, you have to include the module when using jruby/warble. However, this step is not necessary when using MRI and the rails server.
I added this to my ApplicationController and it worked:
class ApplicationController < ActionController::Base
include ActionController::Caching::Sweeping if defined?(JRUBY_VERSION)
...
end

Related

Undefined method `each' for nil:NilClass (NoMethodError) when Memcached is unavailable

My production application uses Memcachier as a cache store for Rails.
The client is dalli and it's configured in my application using :dalli_store and the memcachier gem.
If Memcachier is down in my logs I can see the following error:
app error: undefined methodeach' for nil:NilClass (NoMethodError) `
Exceptional doesn't warn me of those exceptions.
Is there a way to make the app more resilient and avoid that exception?

Rescuing Redis Exception in Rails

I currently have a Rails 3.2.13 app using redis as its cache_store and for Sidekiq.
I'm also using redis master-slave. I ran into an issue where during failover a slave would be in the process of becoming master, Rails then connected to this node and once it tried to write to the node, even though the node was master, this exception was raised:
Redis::CommandError: READONLY You can't write against a read only slave.
vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis/client.rb:85:in `call'
vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:1181:in `block in srem'
vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:in `block in synchronize'
/usr/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:36:in `synchronize'
vendor/bundle/ruby/1.9.1/gems/redis-3.0.4/lib/redis.rb:1180:in `srem'
vendor/bundle/ruby/1.9.1/gems/redis-namespace-1.3.0/lib/redis/namespace.rb:306:in `method_missing'
vendor/bundle/ruby/1.9.1/gems/sidekiq-2.11.2/lib/sidekiq/manager.rb:123:in `block in clear_worker_set'
vendor/bundle/ruby/1.9.1/gems/connection_pool-1.0.0/lib/connection_pool.rb:48:in `with'
vendor/bundle/ruby/1.9.1/gems/sidekiq-2.11.2/lib/sidekiq.rb:67:in `redis'
vendor/bundle/ruby/1.9.1/gems/sidekiq-2.11.2/lib/sidekiq/manager.rb:118:in `clear_worker_set'
vendor/bundle/ruby/1.9.1/gems/sidekiq-2.11.2/lib/sidekiq/manager.rb:45:in `block in stop'
vendor/bundle/ruby/1.9.1/gems/sidekiq-2.11.2/lib/sidekiq/util.rb:15:in `watchdog'
vendor/bundle/ruby/1.9.1/gems/sidekiq-2.11.2/lib/sidekiq/manager.rb:33:in `stop'
vendor/bundle/ruby/1.9.1/gems/celluloid-0.14.0/lib/celluloid/calls.rb:25:in `public_send'
vendor/bundle/ruby/1.9.1/gems/celluloid-0.14.0/lib/celluloid/calls.rb:25:in `dispatch'
vendor/bundle/ruby/1.9.1/gems/celluloid-0.14.0/lib/celluloid/calls.rb:125:in `dispatch'
vendor/bundle/ruby/1.9.1/gems/celluloid-0.14.0/lib/celluloid/actor.rb:328:in `block in handle_message'
vendor/bundle/ruby/1.9.1/gems/celluloid-0.14.0/lib/celluloid/tasks.rb:42:in `block in initialize'
vendor/bundle/ruby/1.9.1/gems/celluloid-0.14.0/lib/celluloid/tasks/task_fiber.rb:9:in `block in create'
I know the issue could easily be resolved by disconnecting anything that's using redis (e.g. sidekiq, rails cache_store) so that any subsequent commands that write to that node would reconnect with a valid connection.
The issue is where to catch and handle the exception? My initial thought was to do an airbrake kind of global rescue but not sure if that would be the best way to go about it.
Has anyone run into this issue?

Passbook IOS6 sends HTTP DELETE to Rails 3.0.3 server, No route matches

I get "No route matches" when Passbook, on iOS6, sends my server an HTTP DELETE route.
In config/routes.rb, the route looks like:
delete "/v1/devices/:device_id/registrations/:pass_type_id/:serial_number" => "registrations#destroy"
and when I run "rake routes" I can see the route is there:
DELETE /v1/devices/:device_id/registrations/:pass_type_id/:serial_number(.:format) {:controller=>"registrations", :action=>"destroy"}
but when the route comes in to the Rails 3.0.3 development server as
Started DELETE "/v1/devices/515a5c955dcdd66f558e1b4041392bf3/registrations/pass.com.myserver.FreeDrink/11" for 192.168.0.22 at 2012-12-23 15:03:25 -0500
the rails server says:
ActionController::RoutingError (No route matches "/v1/devices/515a5c955dcdd66f558e1b4041392bf3/registrations/pass.com.myserver.FreeDrink/11"):
actionpack (3.0.3) lib/action_dispatch/middleware/show_exceptions.rb:53:in `call'
railties (3.0.3) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.4) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.3) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.2.4) lib/rack/lock.rb:11:in `block in call'
<internal:prelude>:10:in `synchronize'
rack (1.2.4) lib/rack/lock.rb:11:in `call'
actionpack (3.0.3) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.3) lib/rails/application.rb:168:in `call'
railties (3.0.3) lib/rails/application.rb:77:in `method_missing'
railties (3.0.3) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.2.4) lib/rack/content_length.rb:13:in `call'
rack (1.2.4) lib/rack/handler/webrick.rb:52:in `service'
/home/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/home/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/home/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
All the other routes, using HTTP GET and POST work fine. This is the only route I'm having trouble with. I know that some browsers don't send HTTP DELETE, only HTTP GET and HTTP POST, and rails puts something in the header to indicate that the request is a delete, but it is Passbook that is sending the HTTP DELETE request, so I don't know if that has anything to do with the problem.
I've also tried other flavors of the route in config/routes.rb such as:
match "/v1/devices/:device_id/registrations/:pass_type_id/:serial_number" => "registrations#destroy", :via => :delete
and I've also tried using other controllers.
Any one know why Rails says that "No route matches" when the request is an HTTP DELETE?
I finally got the delete route to work by using the route from this post
delete "/v1/devices/:device_id/registrations/:pass_type_id/:serial_number" => "users#delete_pass", :constraints => { :pass_type_id => /[^\/]+/ }
which has the constraint added:
:constraints => { :pass_type_id => /[^\/]+/ }

Undefined method failure_app for nil:NilClass

I am trying to use devise from a Rails app to grant access to a Sinatra application within the Rack middleware.
My config/routes.rb has:
authenticate "admin" do
mount Admins::Dashboard, :at => "/admins"
end
In my Sinatra app, I use:
before do
env["warden"].authenticate!(:scope => "admin")
end
get "/dashboard" do
erb :dashboard
end
Now, I get an error with the following stacktrace:
Started GET "/admins/dashboard" for 127.0.0.1 at 2012-10-11 08:45:13 +0200
NoMethodError (undefined method `failure_app' for nil:NilClass):
devise (2.1.2) lib/devise/delegator.rb:11:in `failure_app'
devise (2.1.2) lib/devise/delegator.rb:5:in `call'
warden (1.2.1) lib/warden/manager.rb:130:in `call_failure_app'
warden (1.2.1) lib/warden/manager.rb:116:in `process_unauthenticated'
warden (1.2.1) lib/warden/manager.rb:47:in `call'
actionpack (3.2.8) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.4.1) lib/rack/etag.rb:23:in `call'
rack (1.4.1) lib/rack/conditionalget.rb:25:in `call'
The error message is a complaint about missing configuration for customizing the warden failure app to point to sinatra.
Check out this previous answer and the related (detailed) blogpost about setting up Sinatra+Warden & Rails+Devise; hopefully the instructions there will help you implement the solution successfully.
Had the same error message and this comment on Github helped me out.
In my sessions_controller.rb I had:
sign_in(:user, #resource, store: false, bypass: false)
which I replaced with:
sign_in(:users, #resource, store: false, bypass: false)
for it to work.
Specifically, the issue was only happening after one user would delete his account... Also I am using devise_token_auth (hence the overriden sessions controller).

jruby multipart post fails for files larger than 800k or so

I have a jruby application deployed using glassfish-gem with an apache front end. When I do a form post of a file it fails on files over a certian size, seems to be around 800k. The error is below if it helps any.
glassfish.yml is generated, no changes from default other than to increase some java memory settings.
I have bypassed apache and gone straight to the app but still have issues. Enabling threading in rails makes the problem worse.
INFO: /!\ FAILSAFE /!\ Fri Oct 29 04:54:17 +0000 2010
Status: 500 Internal Server Error
Stream closed
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/rack-1.1.0/lib/rack/utils.rb:466:in `parse_multipart'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/rack-1.1.0/lib/rack/request.rb:268:in `parse_multipart'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/rack-1.1.0/lib/rack/request.rb:146:in `POST'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/facebooker-1.0.75/lib/rack/facebook.rb:38:in `call'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/actionpack-2.3.10/lib/action_controller/session/cookie_store.rb:100:in `call'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/actionpack-2.3.10/lib/action_controller/failsafe.rb:26:in `call'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/rack-1.1.0/lib/rack/lock.rb:11:in `call'
/var/www/LocalHabit/shared/bundle/jruby/1.8/gems/actionpack-2.3.10/lib/action_controller/dispatcher.rb:106:in `call'
/usr/local/rvm/gems/jruby-head/gems/glassfish-1.0.3.dev-universal-java/lib/../lib/rack/adapter/rails.rb:133:in `call'
/usr/local/rvm/gems/jruby-head/gems/glassfish-1.0.3.dev-universal-java/lib/../lib/rack/handler/grizzly.rb:55:in `call'
:1
Oct 29, 2010 4:54:17 AM com.sun.grizzly.http.SocketChannelOutputBuffer flushChannel
FINEST: flushChannel isAsyncHttpWriteEnabled=false bb=java.nio.HeapByteBuffer[pos=0 lim=1088 cap=33368]
Turns out there was a bug introduced in jruby version 1.5.1, that is supposedly fixed in 1.5.6, but I misplaced the details on the bug. It was actually related to a post issue in jruby in general.