Currently, caching has limited easy use because side-effecting operations are not repeated when the cached item is loaded.
For example, a function building the front page might return the content but also add a stylesheet and an RSS feed header. If only the results of the front-page-building function are cached, loading the cached version requires either manually repeating the side effects or awkwardly storing the side-effects in the cache for replay. As function calls get deeper, predicting and replaying these side effects becomes very difficult.
We could improve such caching by having a hook_side_effect that is called whenever side-effecting operations run. hook_side_effect would be called with the function name (e.g. 'drupal_add_js') and the array of arguments the function received. Caching modules could implement the hook to record and replay side effects when the cached item is retrieved.
Comment | File | Size | Author |
---|---|---|---|
#11 | js_side_effect_detection_0.patch | 1.03 KB | David Strauss |
#8 | js_side_effect_detection.patch | 1.03 KB | David Strauss |
#6 | alt_side_effect_detection.patch | 1.03 KB | David Strauss |
#3 | side_effect_cache.patch | 1.19 KB | David Strauss |
Comments
Comment #1
David StraussAdd this:
module_invoke_all('side_effect', __FUNCTION__, func_get_args());
to following are side-effecting functions:
This will allow caching modules to log and replay side-effects on cache restoration.
Comment #2
David StraussWhoops, didn't notice that the title changed the entire bug/feature report. Should have read the descriptive text...
Comment #3
David StraussHere's a patch to a current HEAD checkout. I tried to minimize the hook calls to when actual effects happen. I'm sure this could be improved further.
Comment #4
David StraussI'd like feedback over whether its better to implement this as a hook or to simply compare the arrays before a function call and after to identify additions. The latter would be more complicated but possibly faster in the common case (no cache).
Comment #5
David StraussGiven the arbitrary values for $scope for drupal_get_js() and the inability to simply load the whole array for all scopes, it seems impossible to determine what core side-effects a function has used by probing for changes.
Comment #6
David StraussHere's an alternative patch that at least allows retrieving the entire array of JavaScript for all scopes. This has a clear performance advantage over adding hook_side_effect, but it's not as extensible. hook_side_effect could be used to record arbitrary side-effecting calls. This alternative patch would require the cache to probe for side effects in specific places.
Of course, a hybrid approach is possible, too. The cache could probe core modules for side effects but still implement hook_side_effect for arbitrary additional effects.
Comment #7
RobRoy CreditAttribution: RobRoy commentedYou got a TAB in there. Use two spaces instead for indents.
Comment #8
David StraussUpdated to remove tab.
Comment #9
David StraussComment #10
RobRoy CreditAttribution: RobRoy commentedHeh, you added some trailing whitespace in there now. Not trying to be a pain in the ass, I swear.
Comment #11
David StraussNo biggie. Whitespace removed.
Comment #12
catchNo longer applies.
Comment #13
PanchoNot sure about this. I like the more extensible original idea. This would be an API change though. Tempted to move this to the D7 queue.
Comment #14
catchDuplicate of #565496: Allow dynamic attaching of other types of stuff to render() structures.