Proposal for a complement to Sweepers to expire Rails cache

Hi, I wish to ask you if could be a good idea to introduce in Rails a simple complement to Sweepers that could reduce the effort of expiring cache, something like that:

Rails.cache.fetch(“recent_posts”, :expires_when => [:create, Post])

The above example could setup a callback to expire “recent_posts” each time that a Post is created.

Sometimes I would like to rely on something like that to expire cache in place of sweepers/observers. What do you think? There may be downsides with this approach?

What's inadequate about this?

Sigh, I'm an idiot and mis-read your email. Please ignore my last one. :[

No problem :wink:

Hi, I wish to ask you if could be a good idea to introduce in Rails a simple complement to Sweepers that could reduce the effort of expiring cache, something like that:

Rails.cache.fetch("recent_posts", :expires_when => [:create, Post])

The above example could setup a callback to expire "recent_posts" each time that a Post is created.

I'm not really a fan of this. When I read this code, it's difficult to understand how ":create" is related to "Post". The other problem is that if I were to read the file that defines Post, I would not be able to understand the impact of Post on the entire system.

Sometimes I would like to rely on something like that to expire cache in place of sweepers/observers. What do you think? There may be downsides with this approach?

Can you explain the problem you're trying to solve? Maybe we can work from there to come up with a better solution.

You could probably hook up something similar using ActiveSupport::Notification and instrumenting the create action in the Posts controller, or alias_method_chain the create method on Posts to do what you want.

@ Aaron Patterson

I’m not really a fan of this. When I read this code, it’s difficult to understand how “:create” is related to “Post”.

Yes, I’ve not focused too much on the syntax, probably there are a lot of better ways to express the same thing, also it would been better if i’ve used an example with fragment cache in views.

The other problem is that if I were to read the file that defines Post, I would not be able to understand the impact of Post on the entire system.

I have a question here: how much expiring cache is supposed to be tight to the model? Is really a good idea to have models or even controllers generally aware of what needs to be expired?

Here it’s ok to couple caching with model since retrieve the “most recent posts” is a business domain feature:

class Post

class << self

	def most_recent_posts

		Rails.cache.fetch ...

	end

end

end

using an observer or decorator here is also fine to create a separate layer that adds caching behavior. Sweepers are better when we need to control cache at controller/application logic level (page/action/requests …).

But in this second snippet it’s not ok to have the model/controller knowing what needs to be expired since it’s something only related to views:

inside Post or PostSweper

after_create

expire_fragment: "list_of_the_most_recent_posts"