APC engine sets timestamps as TTL when not using CACHE_TEMPORARY or CACHE_PERMANENT

neilnz - May 14, 2009 - 22:30
Project:Cache Router
Version:6.x-1.0-beta8
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:closed
Description

There's a somewhat major flaw in the apc.php engine. apc_store() takes the cache expiry as a TTL value (number of seconds until it should be purged), whereas cache_set() takes it as a UNIX timestamp value of when the entry should expire. The engine fails to do the conversion, so if something is stored in the cache for a specific lifetime, it ends up being in the APC cache for decades, when it may only be supposed to be a few seconds.

Patch attached.

AttachmentSize
apc.expire.patch1.12 KB

#1

TBarregren - June 17, 2009 - 10:18

This is a bug in 5.x-1.0-beta9 as well.

#2

neilnz - June 17, 2009 - 20:52
Status:active» needs review

#3

davea - June 25, 2009 - 18:06

I am testing this.

#4

neilnz - July 13, 2009 - 00:02

davea - any output from this?

Getting a bit annoying having to apply this patch to every new site, would be nice to get it RTBC.

#5

andypost - July 16, 2009 - 22:55

#6

neilnz - July 16, 2009 - 23:10

No, it's not. While this may be an issue for other engines as well, this is simply to provide the behaviour that APC itself may expire an item once it passes its stated expiry, negating the need for cache_clear_all(). For a memory-backed cache like APC or memcache, this is an important capability as the cache reaches capacity. APC's behaviour if the cache fills up and it has nothing expirable is to purge the entire cache.

It sounds like from #266588: Obey "expire" value on cache_clear_all(), like Drupal core that memcache may automatically detect that you're using a timestamp rather than a TTL and compensate for that internally, but APC doesn't.

This is very definitely a serious bug in the APC engine and unrelated to cache_clear_all(). The effect is that cacheable blocks never get regenerated until the web server is restarted, which is really annoying.

#7

andypost - July 17, 2009 - 23:02
Status:needs review» needs work

@neilnz What for?

<?php
+    $return = null;
?>

But I still thik about common solution about lookups locking and TTL length

#8

neilnz - July 19, 2009 - 21:15

Sorry, that $return thing was another modification I made to prevent it spitting out E_NOTICE errors when it fails to get a lock. You can leave it out if you like.

#9

Jonah Ellison - July 20, 2009 - 00:13

I believe this issue is related to #266588: Obey "expire" value on cache_clear_all(), like Drupal core.

We cannot negate the need for cache_clear_all() because caching engines must follow Drupal core caching rules.

Here is a scenario:

cache_set() stores a record for "CACHE_TEMPORARY" number of minutes (i.e., no specific expiration time is given). Now a module calls cache_clear_all() since it needs to wipe these temporary cache records. The APC engine must clear the records immediately.

Now another module stores a record using the unix timestamp. cache_clear_all() is called and the APC engine must ignore all records with a future unix timestamp.

If the timestamp is converted to a cache specific time, how does the APC engine differentiate between the temporary records and the unix timestamp records?

#10

neilnz - July 20, 2009 - 02:26

Well APC isn't capable of doing either of these reliably. It has an identical set of issues to memcache in this regard. The only thing it knows how to do is throw records out when they pass expiry.

If you want the ability to control when things get deleted using PHP code, you'd have to store everything as a permanent item in APC, then keep an index of all cached items and refer to that to know what to purge. That's not a very efficient use of APC and negates a lot of the reasons to choose it over a file or database backed cache.

In the current implementation, a CACHE_TEMPORARY is kept in APC for 180 seconds, which is not standard Drupal behaviour. A cache_clear_all() will not touch it.

The Drupal core cache mechanism is not really designed to fit the model of self-invalidating caches, so I don't think it's necessarily a good idea to force memcache and APC to behave like core, as the cache is one thing you don't want to unnecessarily slow down for the sake of compliance.

Certainly I've had absolutely no issues with using my patch from above in many live sites with a large variety of contrib installed on them.

#11

slantview - September 3, 2009 - 11:28
Status:needs work» fixed

Committed patch. Thanks!

#12

System Message - September 17, 2009 - 11:30
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.