[development] 5/6: cache_clear_all(), custom items, and no cache_lifetime > failure

Morbus Iff morbus at disobey.com
Mon Jun 23 13:51:34 UTC 2008


Michelle ran into it long ago in her Advanced Forum module, and I ran 
into it a while back in regards to blocks. I just ran into it again 
today in a non-block scenario. In short:

   http://www.lullabot.com/articles/a_beginners_guide_to_caching_data
   will only work if you have a "Minimum cache lifetime" set.

   Cache expiration, for items with a custom expiration, will never
   automatically occur, as cache_clear_all('', 'cache') is never called.

   This happens in Drupal 5 and 6.

There are three ways that cache can be expired:

  1) you manually expire your own entry.
  2) cache_clear_all() is called with the right parameters.
  3) cache_get() is called, with a minimum cache_lifetime set.

For now, let's safely ignore 1) since the explanation of cache_set() 
suggests that setting your own expiration timestamp treats the item as 
CACHE_TEMPORARY, and that it'll be flushed in the next general clear.

Also ignore #3 - let's assume no minimum cache lifetime was set.

If we take a look at cache_clear_all():

   http://api.drupal.org/api/function/cache_clear_all/5
   http://api.drupal.org/api/function/cache_clear_all/6

we can see the helpful comment of "No minimum cache lifetime, flush all 
temporary cache entries now." To get this code to run, however, the $cid 
must be empty *and $table must be set to 'cache'*. If both cid and table 
are empty, then the function defaults to clearing cache_block and 
cache_page.

But, if you grep for "cache_clear_all()" in core, you'll never find an 
instance of "cache_clear_all(NULL, 'cache')". You'll see lots of 
"cache_clear_all()"s with no parameters, and lots of specific clearing, 
but nothing that specifically clears out temporary items in 'cache'. You 
won't even see a "destroy everything" cache_clear_all(*, 'cache', TRUE).

I consider this a bug:

  * garbage collection should happen automatically - else, why would
    a calling module tell cache_set() about the expiry date if it's
    the module's responsibility to clean it up?

  * "Minimum cache lifetime" is a performance tweak, and should
    not be required to properly clear CACHE_TEMPORARY items.

How to fix the bug? Honestly, I don't know - one would, presumably, add 
a cache_clear_all(NULL, 'cache') to a hook_cron implementation, but I'm 
not the one to know the best location for that. Suggestions?

And, naturally, if my reasoning is all wrong, lemme know too.

-- 
Morbus Iff ( if god is my witness, god must be blind )
Technical: http://www.oreillynet.com/pub/au/779
Enjoy: http://www.disobey.com/ and http://www.videounderbelly.com/
aim: akaMorbus / skype: morbusiff / icq: 2927491 / jabber.org: morbus


More information about the development mailing list