Why is Rails + webpack + split chunking serving up slow requests on localhost? - ruby-on-rails

I have a Rails (puma) app with webpacker (webpack). I'm doing split chunking on ~40 of my pages at the routing level. When I run the app locally my requests start to slow down (see img below) after about an hour of running the server. I'm not sure why. If I kill my rails server and/or webpack dev server and restart them it still continues to be slow (If I restart my machine it'll go back to being fast. haha).
Any ideas how to fix or debug this?
// rails console output for this page:
#method=GET path=/invite format=html controller=HomeController action=index status=200 duration=154.88 view=154.15 db=0.00

Related

Rails with unicorn showing 2 different version of same page

I have a rails 4.1 app that is using nginx and unicorn.
Lets say I make a change to html of a page and push it live. If I navigate to that page or refresh it, I randomly get either the old page or the new updates.
This happens with assets as well. For example refreshing a page will get me either the old version of my css file or the newest version. Obviously this causes a ton of issues.
I am using the default asset pipeline.
I've tried running rake:tmp:clear. I've tried using Rails.tmp.clear from Rails production console. Neither have worked.
This is a really strange issue that I can't seem to get my head around.
Check out the pid of your unicorn with ps au | grep unicorn, it may freeze after update.
If afrer kill -USR2 unicorn pid is the same you should restart unicorn hard with kill -9 unicorn and run it back or run deploy script again.

Rails when served by unicorn is generating the wrong fingerprint for precompiled assets

I have a production server with nginx -> unicorn -> rails. I precompile assets, which puts assets in public/assets with a fingerprint (hash) appended to the filename. However, when a web page is requested, references to application.css and application.js assets will have the wrong fingerprint. For example, the rails helper stylesheet_link_tag will generate a filename that does not exist in public/assets on the server, because the requested fingerprint does not match the precompiled one. Image assets work fine (fingerprints match).
Troubleshooting this, I precompiled assets on my local machine, and the fingerprint matches the precompiled fingerprint on my server. Moreover, when running locally with webrick in production mode, everything works. I then tried running webrick on my server, which worked, making me think unicorn is the source of the problem.
I have solved this problem by starting unicorn with the --no-default-middleware (or -N) option, and this makes unicorn behave as expected with respect to precompiled assets. My understanding is that this tells unicorn not to load a default set of Rack middleware that it would otherwise load. However, I don't really understand why this solves the problem, or what is going wrong in the first place. What is going on?
Some specifics: Ubuntu 12.04, Rails 4.0.1, Ruby 2.1.0, bootstrap 3.0 with a third party theme
Update:
The reason that I don't believe this is an nginx problem is that when I request the page from a browser, and then view source, the filename for the application.css file has a fingerprint, so it actually looks like application-3855b1928b94aa5bff5e1dac1aa56882.css. This does not match the real fingerprint of the file on my server. I am convinced that the fingerprint on the server is correct because I get the same fingerprint on my local development machine. So the client is loading the web page, then asking the server for the .css file...nginx receives that request, but can't find the .css file, because it actually isn't there, so nginx is behaving as expected.
The fingerprint is generated twice: Once when I precompile assets, which is working correctly (pretty sure), and is happening with no unicorn involvement. And a second time, when rails in the context of a unicorn worker sees the stylesheet_link_tag helper and on-the-fly calculates the fingerprint (I think this is what it's doing), which for some reason is generating an incorrect fingerprint. This same process happens if I replace unicorn with webrick on the exact same server, but in this case the fingerprints match. If I start unicorn with the -N flag, the fingerprints match, but I don't know why this makes a difference, and I don't know why nobody else seems to have to do this.
A wild guess: check that Unicorn is actually run in production environment on your sever.
Even we faced the same problem where assets compilation succeeded but things did not work as expected. We found that unicorn was the main culprit here. Same as your case, even we used to restart unicorn after compiling the assets. It was noticed that when unicorn is restarted, only its worker processes are restarted and not the master process. This is the main reason the correct assets are not served. Later, after compiling assets, we stopped and started unicorn so that the unicorn master process is also restarted and the correct assets were getting served. Stopping and starting unicorn brings around 10 secs on downtime when compared to restarting the unicorn. This is the workaround that can be used where as long term solution is move to puma from unicorn.

Why WEBrick server is faster in production mode rather in development mode? + Rails

I have been developing ruby on rails application since some couple of months. I use the default WEBrick server to run the applications. And I found that when I start the WEBrick server in the development and production modes, the server works more speed for production mode than for the development mode.
Is there any specific reason behind that? Can anybody explain me?
In production mode, a server loads code into the cache, which makes things quick. However, that's not the case in development mode (since you don't want to restart your webrick every time you made a change). Every request loads the according code again, which takes a bit of time.
And the most of all time-eaters is the asset pipeline. In production, you get a compiled version of your assets (javascripts and css) in maybe one or two requests. In development, you get them split, for debugging purpose (based on your environment settings, of course). And because a browser does not handle all requests simultaneously, some assets are loaded after other ones are finished loading. You can watch this behaviour with e.g. firebug's network console. That means: the more assets you have, the longer your page takes to load in development mode.
In dev mode classes are not cached, so Rails reloads all the classes each time you refresh. Also, asset compilation is not done in development (by default), so Rails reloads all the assets (CSS, Javascript etc) each time you refresh.
The difference is between 2 environments. In Rails, there are several environment. Each has his own database configuration and Rails options.
You can use the Rails.env variable to made some different change with particular environment.
By default, the development environment is without all cache and activate the auto-reloading. The production environment is with all cache.
But if you want you can make a production environment like development or development environment like production.
You can add some new specific environment too.
Creating new Environment:
Assuming you want create the hudson environment.
Create a new environment file in config/environments/hudson.rb.
You can start by cloning an existing one, for instance config/environments/test.rb.
Add a new configuration block in config/database.yml for your environment.
That's all.
Now you can start the server
ruby script/server -e hudson
Run the console
ruby script/server hudson
And so on.

check 500 internal server error in production mode in rails 3.2

I have my app in production mode in my linode account and I get in one page a 500 internal server error the message:
We're sorry, but something went wrong.
However in my development environment works fine this page.
How can I debug this error?
How can I see the error origin in my production mode?
I want that rails show errors in production mode.
How can I do it?
Thank you!
If you have access to ssh, log in to your server via ssh and go to your rails log directory, which is inside your rails directory.
Once you are there run the command tail production.log . If this doesn't give you enough information you can also do a tail -n100 production.log (gives you last hundred lines of the production log).
If you have deployed via heroku, then you can access the logs by running heroku logs in your local console. (more information here https://devcenter.heroku.com/articles/logging)
I also find it helpful to use the exception_notification gem https://github.com/rails/exception_notification when running in production, as it emails you a stacktrace when an error occurs. Plenty of others also use Hoptoad (http://hoptoadapp.com/) or Exceptional (http://www.exceptional.io/) however i prefer the simple exception_notification gem.
Also, in some rare occasions when i can't trace the error as a final measure i sometimes open up port 3000 temporarily on the remote server firewall and cd to the rails project and run rails server production with the log level set to debug in config/environments/production.rb so i can see the error in the console, and then close off the port when i have finished.
Hope that helps.
tail -n100 production.log
will only show the last 100 lines of the log file. Just in case you want to see the log running in real time.
use this
tail -1000f log/production.log

How to properly diagnose a 500 error (Rails, Passenger, Nginx, Postgres)

I'm having a real tough time diagnosing a 500 error from my application running in production. I've had it working before, but after re-deploying via Capastrano I am unable to get it going.
Here are the facts:
The server is setup with nginx + passenger, and I'm using
PostgreSQL.
Static assets are working properly, as in I'm able to access them just fine in a browser.
I can access the rails console via RAILS_ENV=production bundle exec rails console and perform Active Record actions (like
retrieving data from the db).
Within console, I can run app.get("/"), which returns a 500 error as well (after first showing the query that was run to load
the model).
The production.log file is never written to. I've set permissions 777 on it just for the hell of it. I've also set the log level to
:debug with nothing to show for it.
The nginx log (which passenger also uses) shows no indication of errors, it just notifies about cache misses.
Because nothing of use is being logged, I have no idea what to do here. I've tried setting full permission on the entire app directory with no help. Restarted the server multiple times, nothing. The database is there and rails can clearly communicate with it. I'm not sure what I did to get it to run the first time around. I just don't know why rails isn't outputting anything to the log.
Okay, I figured this out. The app ran fine in development mode, so I knew something production-specific was screwing it up. I went into config/environments/production.rb and changes these settings:
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false # changed from true
config.action_controller.perform_caching = true # changed from false
And then after restarting passenger, rails showed me the error w/ stacktrace. Turns out I was forgetting to precompile the asset pipeline!
Things to check
1) Are you sure you are running in production environment?
Check to see if any entries are in the development.log file
2) Set up your app to email you when a 500 error occurs with a full stack trace. I use the Exception Notifier gem but there are plenty of other solutions for this.
3) When checking your app in the console are you sure you are starting the console in production mode? It is possible that the app is not starting up at all and you just forgot to set the production param thereby thinking that the app runs fine when it doesn't.
4) Are you getting an nginx 500 error or the Rails 500 error? If nginx then it is likely that your app is not starting at all and highly unlikely that you will get any rails error in your log file. The assets are static files and navigating to them proves nothing other than that they exist.
5) Are you sure you are checking the right folder on the server? Sounds really stupid but capistrano could be deploying the app to a folder that is different to the folder that nginx is looking for for your app so double check both the folder capistrano is deploying to and the folder that nginx is looking for are the same.
Just a suggestion, I would use puma rather than passenger. It's awesome with nginx.
My problem is passenger's log file (error.log) has nothing. Then it's a rotation log issue. Run
passenger-config reopen-logs
solved my problem. More.
Have you tried running in development mode to see if the error reports itself?

Resources