cache_sweeper

Hi,

Why is cache_sweeper not a documented method? I was pretty sure it used to be, but I could be wrong. I can't seem to find any information on it anymore in the online docs.

As a side note, looking at the code for cache_sweeper it appears to only work with the :only option, not :except (ignores it)... what's the reason for this?

Thanks, Andrew

Ok, the only documentation that exists for cache_sweeper seems to be at http://api.rubyonrails.com/classes/ActionController/Caching/Sweeping.html

In addition to my comment about why cache_sweeper only accepts :only, I found that the sweeper doesn't even appear to pay attention to anything I pass to :only.

If I do... cache_sweeper :my_sweeper, :only => :test

and call the :update action for example and the observed class in my_sweeper is modified, the sweeper is still run.... even though I told it to only use the observer for the :test action with :only => :test

Does anybody else see something similar in their code?

If what I said above makes no sense, what I'm saying is if you use :only, replace any or all actions you specify in there with anything and the observer will still get called. :only => :somerandomjunk

I'm using rails 2.0.2 btw

I ran into this the other day and it took me a while to figure out what was going on. This is the paragraph in the Rails book (page 460):

"If a request comes in that invokes one of the actions that the sweeper is filtering, the sweeper is activated.

If any of the Active Record observer methods fires, the page and action expiry methods will be called.

If the Active Record observer gets invoked, but the current action is not selected as a cache sweeper, the expire class in the sweeper are ignored. Otherwise, expiry takes place"

I had something similiar. I had a method called upload() in my photo_controller that I renamed to create(), but forgot to change the cache_sweeper:

cache_sweeper :photo_sweeper, :only => [:upload]

My sweeper looked like this:

class PhotoSweeper < ActionController::Caching::Sweeper   observe Photo

  def after_create(record)     return if record.thumbnail?     expire_fragment(%r{photo\/latest})   end end

This obviously made some caches not expire correctly. However, the sweeper was still called, because one tells it to observe photos. However, none of the calls to read_fragment or expire_fragment will work. You can call them--they just return nil and do nothing.

Unlike the before/after/around_filters, the options :only and :except don't dictate whether the callbacks (after_create and others) in the sweeper are called or not. The options dictate whether the cache expiry functions work while in the sweeper or not.

It seems that the sweepers observe according to their Observable behavior--they're essentially active record observers, so they will fire any time the AR class they're observing has a callback. The sweeper options :only, and :except don't filter out calls, but only that the cache expiry functions work.

I too found this a bit unintuitive, given how the before/after/around_filters work. Does anyone else think/feel the same?

Wow, so that's what it's doing. This explains the other "issue" I was experiencing and that is with one of my other sweeper callbacks being called that I specified from an entirely different controller (due to the Observer being active at all times).

As the current "documentation" is right now, I'd sure say the way this method works is unintuitive. cache_sweeper actually does a number of other things that I was only able to extract from looking at it's code. It allows (before|after)_controllername_action type methods to be used as well, but the only place I've seen this documented is the CHANGELOG from ages ago. :slight_smile:

Thanks for the comment Will.