Today we realized that the project is evolved enough to take some time and think about how we can cache things efficiently.
One of the actions we were in doubt of most seriously is the action that responds to an AJAX call and returns you the position of the trucks that are rolling all over the map.
Some heave stuff going around in the background of this and even if anyone requests it only once in a minute, we wanted a caching solution for that, so that 100 users don’t do 100 requests that are handled by our application in a minute, but 99 requests that are fulfilled by Apache and just 1 which our application has to take care about.
The solution is pretty simple: Page Caching. Ok, this is not a big deal in Rails, but we had to expire the cache with a TTL of 1 minute or maybe 58 seconds. That is not included in the Rails caching mechanisms and even if there are plugins out there that can do exactly that, we decided not to get into them, because we would like to stay as closest as possible to the Rails “core” to keep the way for future colleagues, joining us with the project, very straightforward and not full of third-party-plugin-obstacles.
So: How can we expire the Rails page cache every minute? Hm… just delete the file that it has generated every minute! Cool! Ok, cool for one file whose name we know very well, but not so cool if we want to expire the whole cache. Why? Rails keeps all the generated pages of the page cache just in your public directory.
So public/controller/action.html might be the path to a cached page. This is ok, but wouldn’t it be nice to have something like public/cache/controller/action.html? It definitely would be much clearer and the expiration of the whole cache would be very easy, too.
And it’s really easy to achieve this! Most of the way you have to go is described here and here. But for us there was a little, tricky pitfall: Basically Josh Susser’s howto is great with all it’s Capistrano recipes etc. But as we’re using Apache as the frontend webserver the Rails Envy guy’s article fills the gap for the mod_rewrite modifications that had to be done. Ok, I must admit these changes (if you have a rewrite rule for the normal public/anything/else behavior already) are so minor that you can figure them out by yourself, so did we. But we made a dumb mistake:
This is the rule from the Rails Envy article:
1
| RewriteRule ^([^.]+)$ cache/$1.html [QSA] |
But this assumes that your of the virtual host is like this:
1
| <Directory "/var/www/application/current/public/"> |
Our entry looked like this:
1
| <Directory "/var/www/application/current/public"> |
Aaaaarg! Just one daft, missing slash at the end ruined us the show with 400 - Bad Request errors whose source we could not determine. Sometimes the problem’s solution is as simple as just change the rewrite rule (or the directory entry in the way showed above) to this:
1
| RewriteRule ^([^.]+)$ /cache/$1.html [QSA] |
Ok, pretty simple ;) . And now enjoy your moved cache and thank Josh and Gregg a lot for their posts!
One last thing to add: How do we delete the cache every 58 seconds? With StupidBackground of course ;) !
Yours,
Thorben
FEtMab-Team