Rails extremely slow - ruby-on-rails

Sorry I know this is a generic question, I'll try to provide as much detail as possible
I am running Bitnami Rubystack (3.2.7) on Amazon EC2 Medium instance. and some aspects of Rails are extremely slow, here are some of them:
when logging in (I am using devise gem), if you provide an invalid password, it would take a long time to tell you that the password is invalid.
Sign Up process takes extremely long, responds after about 2 minutes (when all it has to do is run a couple of queries agains the db?)
File uploads (on carrierwave) are so slow they are practically not working. (files are going to S3 via Fog on CarrierWave).
The code in the above instances is pretty straight forward and I don't see anything obviously wrong. In fact, most of the work gets performed by the gems (e.g. devise handles registrations and logins). any help would be greatly appreciated.

Try to use a analytics tool, like New Relic
This will help you locate te slowest code and/or the slowest db query
EDIT
On the comments below you have mentioned that you are using devise 0.5.8, this is very bad, considering that devise is, today, at version 2.1.2
Please update your devise and keep me posted.
NEW EDIT
Since the devise version is not the problem you could look into the views.
In the views check for http requests that could be inserted on a single request or a async request.
For instance Google Analytics.
If the load of their javascript files are blocking your view to load maybe putting them on head or making them async could help

I would suggest you to compile a Ruby 1.9.3-p194 with falcon patch, it increases ruby and rails speed dramatically.
falcon patch in rvm
You download ruby src and apply this patch if you do not want to use RVM.
It might also be a DNS issue if some parameter for reverse DNS lookup enabled in Apache configuration.

Just put gem rails tweak in your gem file and after that run
bundle install
I think it will solve your problem.
Thanks

Related

Sidekiq Forbidden error with Redis sessions

Seeing a Forbidden error when we attempt to retry / delete / etc from the sidekiq UI.
Read through a lot of the web traffic on people who experienced this issue, including: https://github.com/mperham/sidekiq/issues/1289
Running on
rails 4.1.11
ruby 2.2.3
sidekiq-pro 3.0.1
redis 2.8.21
puma
Heroku
redis-rails for storing sessions
relevant snippets from our app: https://gist.github.com/toddmetheny/4b511e364a4c91ad8187
We're using redis to store sessions. It seemed like a fair number of people having the problem were doing that but there were various problems sharing sessions w/ the sidekiq UI.
Tried most of the things I've seen suggested in the related closed issues without any luck. As described by others, it works well in development...and staging (which seems really weird). Was hoping someone might have something to add. Thanks in advance.
Read the comments just posted here:
https://github.com/mperham/sidekiq/issues/2487#issuecomment-179667037
Run bundle update sinatra to make sure you have the latest Sinatra and Rack stuff.
To properly share the session between Sinatra and Rails, you need to do something like this:
Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_token]
Sidekiq::Web.set :sessions, Rails.application.config.session_options

How to block an ip address from linode?

I have rails application running in linode server .Some guy is continuously spamming (writing bullsh*t in my site).Can anybody tell how to block that person ip.Any other help would be appreciated.
I would suggest you don't only look into blocking that one person but rather into making sure this can't happen again.
Spams usually originate from bots that randomly try to fill in their marketing message into input fields on pages they encounter.
You block one, another will find your page and continue.
The only ways to prevent this kind of automated spam I know of are either using some sort of CAPTCHA or by securing your site through authentication.
There are some very nice captcha gems like reCaptcha or look around in the captcha category on Ruby Toolbox and you should be up and running soon.
If it's really a person that is annoying you with writing bad stuff to your site, while not ideal an IP block is easily set up through apache. Just put the following into your VirtualHost file inside the <Directory> node and then enable the mod_authz_host module through a2enmod authz_host
Deny from 192.168.205
You can do this in the web server config file, here is the example for Nginx:
http://www.cyberciti.biz/faq/linux-unix-nginx-access-control-howto/

Rails saving a file from a URL slower than straight Ruby?

I have a Rails app that saves files in mongo. This works great and I have it set up to serve those files, but with some use cases I need to get the file and write it to disk (merging pdf files).
In IRB or from a simple Ruby file I can run the following code and get the file almost instantly, but when the same code is called from within Rails it times out.
require 'open-uri'
open('id1_front.pdf', 'wb') do |file|
file << open('http://127.0.0.1:3000/files/uploads/id1_front.pdf').read
p file
end
-
Timeout::Error (Timeout::Error):
app/controllers/design_controller.rb:38:in `block in save'
app/controllers/design_controller.rb:37:in `save'
Anyone know why it would be timing out in Rails? Any alternate solutions to get a file out of mongo and write it to disk?
thanks!
When you're running your development server, you have only one thread on which to respond to requests. This thread will be blocked when a request is being served: so, you request design_controller#save, which then tries to make another request to the web server for an uploaded file. This request will never successfully complete, because the webserver is still trying to complete the previous one.
You might be able to get around this problem by using thin as your Rails server, instead of webrick. Add gem thin to your gemfile and start your server with rails s thin. I'm not sure if this will allow more than one request to be serviced simultaneously, but it's at least worth a shot.
--EDIT--
After some testing I determined that thin is also single-threaded, unfortunately, so will also have this exact same problem.
After a bit of Googling, I did discover shotgun. It hasn't been active for awhile but it looks like it might fix your problem, since it spawns a new application per request in development. Give it a shot.

Tomcat is processing requests for a JRuby on Rails app before app is completely loaded

I have an edge case, although a very customer visible one, where Tomcat begins processing requests before all dependencies are properly loaded for a Ruby on Rails stack running underneath JRuby.
Once Tomcat is restarted, there is something similar to the following happening:
undefined method `utc_offset' for nil:NilClass
[RAILS_ROOT]/gems/gems/activesupport-2.3.8/lib/active_support/values/time_zone.rb:206:in `<=>'
This happens when the following code is invoked on one of my services:
#timezones = ActiveSupport::TimeZone.all
If you wait a few more seconds and refresh the requesting page, it'll load no problem.
Is there a way to ensure that Tomcat does not start processing these requests until the entire stack, ActiveSupport, ActiveRecord etc is loaded? Has anyone experienced any similar symptoms?
This sounds like a possible bug in JRuby-Rack, assuming that's what you're using to run your Rails app in Tomcat. JRuby-Rack is supposed to load the entirety of config/environment.rb before it will process requests, so I'm not sure how this would happen to you, but perhaps I've overlooked something. Could you share some more data (or maybe code or an app that reproduces the issue) about how you induced the error at http://kenai.com/jira/browse/JRUBY_RACK or http://bugs.jruby.org?
I'm not sure if there is something like that in Tomcat directly, but you can write a javax.servlet.Filter that will intercept all requests, and deny them until your application is loaded. When application is fully loaded, you ask filter to stop denying requests. (This isn't pure Ruby solution though).

Rails - Invalid Authenticity Token After Deploy

We're using EngineYard Cloud to deploy our Ruby on Rails application. We are running Rails v2.3.3.
EngineYard Cloud deploys to AWS instances in a manner similar to Capistrano. After each deploy, we're running into Invalid Authenticity Token errors. Specifically, any user that has previously visited our application and then visits after the deploy and then tries to submit a form gets an invalid authenticity token error. This error persists until they reset their cookies for the site. After they reset their cookies, the site works as expected with no errors.
We are using ActiveRecord's session store and sessions are being saved to the database.
This is the error we are seeing:
ActionController::InvalidAuthenticityToken
/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token'
The session object is nil after the deploy, however, the session data still persists in the database and the session ID cookie still exists:
Session:
session id: nil
data: nil
We haven't been able to explain this one. Any thoughts on what could be the root cause?
Thanks for any suggestions!
EDIT: Just to update on this, we've been able to isolate an example of the error.
1) User loads form
2) Code is updated on server
3) User submits form
** Invalid Authenticity Token error occurs
It seems that when the environment changes, Rails is unable to handle this with the authenticity token.
We've tried several steps to resolve:
Resetting the session
Deleting the session cookie (both in JavaScript and Rails)
Wiping the session table in the database after deploying code
Nothing works. The only thing that works is having the user clear their cookies client-side.
(We've been Googling (even tried Binging!) for answers, but no dice. This seems to be a similar related issue: http://railsforum.com/viewtopic.php?id=21479)
Also: initially we thought this was isolated to our deployment to EngineYard, but we've also been able to reproduce it on our development server that we deploy to via Capistrano.
Any thoughts would be gratefully accepted.
Thanks!
ANSWER: After extensive work by EngineYard (they're awesome!) they were able to diagnose the issue. The root cause of this issue is a bug with mongrel clusters. Mongrel doesn't seem to see the first post request after being started. EngineYard did extensive work to diagnose this:
There doesn't appear to be anything in your code causing the issue and I have found people outside of our environment that have experienced the bug as well (http://www.thought-scope.com/2009/07/mongrelcluster-rails-23x-bad-post.html). I suppose a lot of people don't see it because the first request to a site generally isn't a post or they chalk it up to flukes.
[There is a potential workaround using CURL.] The curl work around would do a simple GET request to each of your mongrels on the server to prime them so to speak. You could do this with capistrano, but that won't work if you deploy via the dashboard. You can find a short section on deploy hooks we have built into the infrastructure here:
https://cloud-support.engineyard.com/faqs/overview/getting-started-with-engine-yard-cloud
Adding a simple run curl http://localhost:500x > /dev/null should work (where x is the port you have 5000-50005 on your current setup).
We have addressed the issue by switching our stack from Mongrel to Passenger, but apparently, a fix for Mongrel is in the works. Hopefully, this helps someone who sees this same strange issue.
The authenticity token is a hidden field on the form that rails checks when the form is submitted to ensure that the post data is coming from a live session.
It is there as a security measure to prevent malicious people from using a form submit on their site to say a delete action on someones account.
You can turn it off on your whole app by adding this to config/environment.rb
config.action_controller.allow_forgery_protection = false
You can turn it off a single controller using
skip_before_filter :verify_authenticity_token
or turn it on
protect_from_forgery :except => :index
check out the ActionController::RequestForgeryProtection::ClassMethods docs for more details
It sounds like the secret key used for authentication is changing when you redeploy, invalidating all existing sessions.
Do you have the configuration parameter config.action_controller.session set anywhere, and if you do, is there anything which would cause it to change when you redeploy?
One of my apps has it configured in config/environment.rb, and a more recent one (generated with Rails 2.3) has it set in config/initializers/session_store.rb. The setting looks like:
config.action_controller.session = {
:secret => 'long-string-of-hex-digits'
}
If you don't have this configured for some reason, rake secret will generate a key for you, which can then be inserted into your configuration.
(If it is — and it's not being changed by your deployment processes — then I have no idea what's going on.)
If it would only be there for mongrels! I'm getting the exact same error on passenger as well (user loads form, deploy, submit -> invalid authenticity token). It'd be interesting to know how you solved the issue by switching to passenger? Any further hints are highly welcome. I'll have a closer look as well...
Cheers!
Have encountered this same problem with Rails 2.3 and a Mongrel cluster where the session secret is definitely set in the session initializer. The problem occured even after clearing the client cookies on the client.
However the suggestion of doing a curl get request across all the mongrels after they restart appears to work - thank goodness someone figured this out because it appears to be pretty darned obscure.
The only added info I can supply we are using Apache mod_proxy_balancer along with https in front of our Mongrels, however this problem was occuring before we turned on SSL. Is anyone seeing this with haproxy as the balancer instead of Apache?
This solved this issue for me :-) :-) :-)
https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4690-mongrel-doesnt-work-with-rails-238#ticket-4690-37 Posted by Mike Bethany
August 30th, 2010 # 06:43 PM.
I've never gone to any length to figure out the details, but for me, this is a client-side data rot issue. If I've been messing around with the way I store my sessions (and therefore, my authorization details,) I get this error from time to time. Clearing out the private browser data; cookies, authenticated sessions, the works, has always solved it for me.
Hope this helps.

Resources