Expire eTAGs when you redeploy
Rails 2.2’s eTAG functionality is great.
def show
@article = Article.find(params[:id])
if stale_record(@article)
# do something expensive
end
end
protected
def stale_record?(record)
fresh_when(:etag => [current_user, record], :last_modified => record.updated_at.utc)
!request.fresh?(response)
end
“304 NOT MODIFIED” all around!
But this determines freshness based on just the record.
If I deploy a new version of the “show” template eTAG-compliant browsers won’t refresh.
I could build my own way of handling this inside “stale_record?”
But Rails already has a method for dealing with this.
All cache keys are generated through the following code.
if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
expanded_cache_key << "#{ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]}/"
end
So what does it mean to be the RAILS_APP_VERSION?
Well, I’m going to mis-use it, and say “it’s the current version of our app”
And Capistrano already gives this to us… it gives us /current/REVISION!!!
Perfect!
A quick “/config/initializers/capified_etags.rb” later
app_version_path = File.join(Rails.root, "REVISION")
if File.exist?(app_version_path)
ENV["RAILS_APP_VERSION"] = File.open(app_version_path).read.strip
end
Nice.
Let me know if there are any other approaches out there.