Current caching strategy uses "cached cards". CachedCard.get() may return a cached card. a cached card is a proxy which handles some method calls-- if they are stored in the cache it retrieves them.
the granular cache strategy makes sense for some kinds of rendering--
"give me line view for card X".. why load all the rest of the stuff?
in some ways, it would be nice to have the caching more integrated with the core api-- so that whenever you're requesting a card, it can come from the cache if it's available there. the trouble with this is that the API for the CachedCard is different from a "real" card. this is for two reasons:
1) a cached card can't do all the stuff a real card can. You can make it so that the cached card will retrieve the real card if you call a method it can't handle, but in that case you're likely defeating the point of going to the cache in the first place.
2) cached cards can respond to some methods that real cards can't-- line_content() for example-- some parts of the cached card are assigned by the rendering layer, and don't really belong in the lower level model.
If the APIs of the objects in fact need to be different, then it makes sense for the caller to have different points of entry so they're choosing on purpose which thing they want.
For now the cached card strategy is working, and there is at least some sense to the reasoning that leads us to this "model" that is nestled in between a real DB model and and the rendering layers. In MVC, Cached Cards are sortof a wrapper around M for special purpose use by V.
Update: some of the need for API integration, for example use in caching templates accessed deep in the system, have turned out to be fairly shallow problems and have been addressed. others still need work; see below
Caching Auto cards is not hard, providing we know when they expire, except that they are usually search cards, and search cards are "uncacheable". We flag cards as "uncacheable" but what we really want most of the time is "post-cache-processing". Here we run into the problem of API mentioned above-- post-cache we have only cached cards, which in the case of search won't have the methods necessary to run the search, and it's not clear how to best differentiate between the different types of cards.
I think we need two things to make this all work.
1) We need to be able to specify some methods that apply to both the card and to cached cards of that type. One solution is to designate a special module name for these method, say "PostCache". Then Card::Foo mixes in Card::Foo::PostCache, and when we create a CachedCard of type="Foo" we also mix in Card::Foo::PostCache.
2) We need to modify the rendering in slot.render to somehow allow cards to interject custom post-cache rendering.
Recent Changes is a special case that needs its own mechanism. One possibility is grouping into a series of changesets. When a card is edited, we check how many changes in the current changeset-- if its over N then we increment $current_changeset_id. in either case, we set card.changeset_id = current_changeset_id.
Then when we go to recent changes we add a condition of most changeset_id=$current_changeset_id (which can be indexed) and boom we've narrowed to the last N revised cards without having to order the whole table by update. the only problem is paging. If N (changeset size) happens to be == page_size, then there may be opportunity for a mapping there. otherwise we have to do funky math to figure out which changesets we need for which page.
just a note:
sql queries on save:
5 - validation
references.rb
9 - expire_cache ( hard_templatees, dependents, referencers, name_references )
12 - update_references_on_update