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.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

David Strauss’s picture

Title: Side-effect function hooks for caching » The addition

Add this:

module_invoke_all('side_effect', __FUNCTION__, func_get_args());

to following are side-effecting functions:

  • drupal_add_css
  • drupal_add_feed
  • drupal_add_js
  • drupal_add_link

This will allow caching modules to log and replay side-effects on cache restoration.

David Strauss’s picture

Title: The addition » Side-effect caching support

Whoops, didn't notice that the title changed the entire bug/feature report. Should have read the descriptive text...

David Strauss’s picture

Assigned: Unassigned » David Strauss
Status: Active » Needs review
FileSize
1.19 KB

Here'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.

David Strauss’s picture

I'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).

David Strauss’s picture

Given 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.

David Strauss’s picture

Here'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.

RobRoy’s picture

Status: Needs review » Needs work

You got a TAB in there. Use two spaces instead for indents.

David Strauss’s picture

Updated to remove tab.

David Strauss’s picture

Status: Needs work » Needs review
RobRoy’s picture

Status: Needs review » Needs work

Heh, you added some trailing whitespace in there now. Not trying to be a pain in the ass, I swear.

David Strauss’s picture

Status: Needs work » Needs review
FileSize
1.03 KB

No biggie. Whitespace removed.

catch’s picture

Status: Needs review » Needs work

No longer applies.

Pancho’s picture

Version: 6.x-dev » 7.x-dev

Not 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.

catch’s picture

Status: Needs work » Closed (duplicate)