fredd wrote:
> 
> This works great until someone changes it's personal information or
> avatar image. So the problem is, how do I invalidate the cache when an
> association gets updated?
> 

Page cache is a big hammer when maybe 1 attribute of 1 related entity 
has changed. What if you cached the row entry for each event?

Users are related to Events, no?  And the User model knows what other 
models it is related to, and the IDs of those related models.  So when a 
User model receives a change to something that appears in some other 
models cache somewhere, it could invalidate (delete) that cache.

I did have a debate with a colleague over which model should be 
invalidating what cache fragment, but my perspective is that the model 
whose data is being shown in a particular cache fragment is responsible 
for invalidating that cache fragment, not the model whose view that 
cache fragment appears in, if that makes any sense.

I have a side bar for 'show' views that lists models 'related' to the 
model being shown. Determining and rendering that sidebar can be very 
expensive depending on the number of related models, and instances of 
those related models.

That sidebar uses fragment caching at 2 levels:
1. the overall 'relateds' cache, which is the whole sidebar
2. a 'model type' cache, which is all the related models of type X, 
which is a portion of the sidebar (each model shows its name, your User 
seems to show the name and avatar)

Generally each model manages its own fragment caches. When data for a 
model changes, each model knows what other models it is related to, and 
their IDs. Given the relationship, each model also knows which types of 
fragment caches its data appears in, and it invalidates (deletes) those 
fragments when fragment cached data changes. Not all the fields trigger 
this behavior, just those that appear in fragment caches.

Suppose 'Feature' 7 is related to 'Project' 13.
Feature 17 appears in the:
 project.13.relateds cache fragment (the whole sidebar)
 project.13.related.features cache fragment (the features portion of the 
sidebar)

When Feature 7's name changes, it knows it is related to project 13, and 
deletes the relateds fragment for project 13, and the related.features 
sub-fragment for project 13.

When project 13 needs to show its sidebar, it finds the sidebar cache 
fragment missing and reconstructs it. The reconstruction finds that the 
sidebar for a Project is actually composed of 9 sub-fragments (Projects 
have 9 related models).

Eight of those cache fragments are found, but Project 17 reconstructs 
the Features sub-fragment (Feature 7 was only 1 of 11 related Features) 
and caches it, then finishes the entire sidebar, and caches that also.

The next time project 13 'shows', it'll find the full sidebar cache 
fragment and just use that.

Fragment caching really helped the performance. Displaying project 13 
which has 40 related models in 9 related types with all fragment caches 
deleted == "Completed in 1728ms (View: 164, DB: 300)", displaying 
project 13 with all cache fragments present == "Completed in 76ms (View: 
66, DB: 3)".

And this is all file-based caching... haven't needed memcached yet.

-- 
Posted via http://www.ruby-forum.com/.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to