Any comments on this ActionCaching patch?

I've been struggling a bit with ActionCaching's handling of different formats - it doesn't seem very well behaved when trying to present a single resource in different formats. In particular, it only uses the path to determine the cache extension to use, so trying to do something like curl -H "Accept: application/xml" http://foo.com/stuff is going to read/write from stuff.cache rather than stuff.xml.cache

Also, ActionCachePath uses the controller to figure out the path to use, even when expiring actions. As such, if you do an xml POST, expiring the cache with expire_action :controller => :stuff is going to affect stuff.xml.cache. (IIRC, expire_action :controller => :stuff, :format => :xml would expire the stuff.xml.xml.cache...)

http://dev.rubyonrails.org/ticket/11184 tries to address both these issues. Any comments would be appreciated.

Cheers, Jon

This sounds a lot like some mysterious caching bugs we are having. We'll take a look at your patch to see if it solves our problems...

Thanks, -- Chad

Any luck with that patch, Chad, or was it an unrelated problem?

It won't be until we look into our bug, which might be a while for this project. I've put links for this thread/ticket in our bug report though, so I'll let you know what we eventually find.

Hi, we work with Chad and we just implemented the fix he was promising.

The good news is that we did confirm that it's a problem with Rails core, and we can probably provide a very simple test case to reproduce it on any Rails app using caching. (Funny thing: we tracked down the last time it happened in our logs and it turned out the client making the fatal request was FeedTools, a Ruby library for fetching and creating RSS type feeds. So in our test, we used FeedTools itself to reproduce the bug and solve the problem.)

The bad news is that your patch didn't fix the problem. We had to resort to overriding the cache_page method in our application controller. Our code is not ready to be rolled back into Rails Core because it hardcodes only the three mime types we care about instead of using Mime::Type's lookup feature. A proper patch would take into account all the possible mime types that are suitable for caching and it would take someone much more knowledgeable than us about Rails innards to do it right.

FWIW, here's our monkey patch:

class ApplicationController < ActionController::Base ...   def cache_page(content = nil, options = {})     return unless perform_caching     self.class.cache_page(content || response.body, cache_path)   end

  def cache_path     # Note: this is a monkey patch for a bug in Rails caching, see     # http://groups.google.com/group/rubyonrails-core/browse_thread/thread/22430d01c6c4010     cache_path = request.path     extension = {       "application/atom+xml" => ".atom",       "application/rss+xml" => ".rss",       "text/html" => ".html"     }     request.accepts.each do |mime_type|       s = mime_type.to_s       if extension[s]         cache_path += extension[s]         break       end     end     cache_path   end

To reproduce the issue, here's what you do:

1. gem install feedtools 2. clear your cache 3. use FeedTools to hit your page (in our case, /blabs) -- note that it's not specifying .atom in the URL, but in the Accept header   require 'feed_tools'   feed = FeedTools::Feed.open("http://example.com/blabs&quot;\)   p feed.title 4. Hit your page in a web browser and see that instead of HTML, your page is XML

Thanks for blazing the trail!

- Shifra and Alex

That's presumably page-caching rather than action-caching, right?

That's presumably page-caching rather than action-caching, right?

Yes, that's right, on this app we're doing all page caching, no action or fragment caching.

- A

prod for further comments...