3 ms·
What I did in Rails on a previous app was: - Tie hooks into the logger so I can track exactly which ActiveRecord models are accessed in a given page view. - H
by caffeine 17y ago
What I did in Rails on a previous app was:
- Tie hooks into the logger so I can track exactly which ActiveRecord models are accessed in a given page view.
- Have 100% test coverage AND make sure coverage pattern (i.e. frequency distribution of line execution) at least looks something like production AND use subset of production data for testing.
When tests are run:
- Use the logger hooks to build the tree of partials included in each view, and models included in each view/partial (i.e. we got a User which had Friends and an Avatar which had a PicResource .. etc.), where the models are linked by foreign key relations, and pages/partials linked by inclusion. This is why you need 100% coverage & real data - you don't want to miss anything.
Then:
- Tie cache-busting code to ActiveRecord's after-save hook. When a table is updated, you go to every tree in which that model appears and go up until you hit the highest partial. You bust the partial and then you bust the top-level page.
- If you want to tune this further (for expensive pages), you can differentiate between CREATE and UPDATE. On CREATE you need to bust the whole cache for those partials/pages. On UPDATE you only need to bust existing cached renders of those pages. So you can just store the N most-viewed pages/partials with those models, and keep their IDs around.
Why we did this:
I realize this isn't typical for a web app. Our app had to render binaries for embedded devices, so we had to compile everything into a single file before it went out the door. This was a highly interactive app, so pages changed all the time. Using this system, we could:
a) maintain quick response times by almost never rendering on page view (rendering was compute-intensive and required about 500ms per page)
b) pre-render often-used and often-changed pages
c) save our precious database from wear and tear
d) do all this WITHOUT harassing the page/content developers, who could throw together new rails views/controllers using whatever AR models they please, without having to maintain onerous "cache-busting" lists or strict model-controller ties.
(I've omitted some details here, like dealing with cyclical dependencies .. no fun otherwise :)