[development] 5/6: cache_clear_all(), custom items, and no cache_lifetime > failure
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:
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():
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
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 )
Enjoy: http://www.disobey.com/ and http://www.videounderbelly.com/
aim: akaMorbus / skype: morbusiff / icq: 2927491 / jabber.org: morbus
More information about the development