Rails page caching and monitor services

This evening, I added page caching to a Rails app I’m building. I want to cache the top page of the site (the index action), so I added the caches_page :index to the correct controller.

All was going well until I deployed to a ‘production’ server.

Doing a View/Source on my web page, I see urls that looked like http:// /foo/bar with a space replacing the server name. This isn’t good.

It took me a few minutes of looking at the Rails production log to see that, about every 60 seconds, something was hitting my site without a server name. What hits my site every 60 seconds? Monit does!

For each of my Mongrel instances, I have a monit configuration that contains the line if failed port xxxx protocol http. This technique doesn’t send a server name when it does the test.

Why is this a problem?

Since monit is hitting the root of the web site, the cached url is what gets accessed. Since I have monit hitting the Mongrel instances directly, the page cache is bypassed, and a broken version of the page is generated and cached. Within 60 seconds, my site is broken!

What do I do?

I solved this by adding a ‘heartbeat’ action to my site that renders the text ‘OK’.

1 def heartbeat
2    render :text => "OK"
3  end

I now have my monit configured to access the url instead of the port checking. This is also much lighter load than hitting the main page of the site.

1f failed url http://127.0.0.1:xxxx/main/heartbeat content == "OK"