I can't figure this out for the life of me. Trying to use Rack::Cache to cache some of my static public pages on Heroku, in addition to doing action caching in case it gets past the reverse proxy.
For example, here's the code in my "home" action:
class StaticPagesController < ApplicationController
layout 'public'
caches_action :about, :contact, ......, :home, .....
......
def home
last_modified = File.mtime("#{Rails.root}/app/views/static_pages/home.html.haml")
fresh_when last_modified: last_modified , public: true, etag: last_modified
expires_in 10.seconds, :public => true
end
For all intents and purposes, this should have a public cache-control tag with max-age 10 no?
$ curl -I http://myapp-staging.herokuapp.com/
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: text/html; charset=utf-8
Date: Thu, 24 May 2012 06:50:45 GMT
Etag: "997dacac05aa4c73f5a6861c9f5a9db0"
Status: 200 OK
Vary: Accept-Encoding
X-Rack-Cache: stale, invalid
X-Request-Id: 078d86423f234da1ac41b418825618c2
X-Runtime: 0.005902
X-Ua-Compatible: IE=Edge,chrome=1
Connection: keep-alive
Am I doing something horribly wrong? I feel like there is something up with that stale, invalid cache response... that is about the 4th time I've hit the page.
Config Info:
# Use a different cache store in production
config.cache_store = :dalli_store
config.action_dispatch.rack_cache = {
:verbose => true,
:metastore => "memcached://#{ENV['MEMCACHE_SERVERS']}",
:entitystore => "memcached://#{ENV['MEMCACHE_SERVERS']}"#,
}
# OLD : Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = true
config.static_cache_control = "public, max-age=2592000"
(Maybe there's a way to manually set the cache-control header? Seems like there should be an easier way though).
UPDATE
I have even tried taking the controller action down to the bare minimum :
def home
expires_in 10.seconds, :public => true
#last_modified = File.mtime("#{Rails.root}/app/views/static_pages/home.html.haml")
#fresh_when last_modified: last_modified , public: true, etag: last_modified
end
And it doesn't work...
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 24 May 2012 19:15:18 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Status: 200 OK
X-Ua-Compatible: IE=Edge,chrome=1
Etag: "733798214c652f39ae79b4037e9111dc"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: b33087fe0c2ae986c4cac88f14420b7c
X-Runtime: 0.006000
X-Rack-Cache: stale, invalid
Vary: Accept-Encoding
X-Varnish: 349105873
Age: 0
Via: 1.1 varnish
!
Maybe rethink the whole thing and just use rails caching. The new cache_digests gem should make it trivial to do what you want at the rails level: https://github.com/rails/cache_digests
I'm willing to bet this will beat your method that includes doing a filesystem call to check the file timestamp every 10 seconds.