diff --git a/classes/Managed_DataObject.php b/classes/Managed_DataObject.php index 106065fc46..1d55537e20 100644 --- a/classes/Managed_DataObject.php +++ b/classes/Managed_DataObject.php @@ -168,4 +168,38 @@ abstract class Managed_DataObject extends Memcached_DataObject } return $links; } + + /** + * Return a list of all primary/unique keys / vals that will be used for + * caching. This will understand compound unique keys, which + * Memcached_DataObject doesn't have enough info to handle properly. + * + * @return array of strings + */ + function _allCacheKeys() + { + $table = call_user_func(array(get_class($this), 'schemaDef')); + $ckeys = array(); + + if (!empty($table['unique keys'])) { + $keyNames = $table['unique keys']; + foreach ($keyNames as $idx => $fields) { + $val = array(); + foreach ($fields as $name) { + $val[$name] = self::valueString($this->$name); + } + $ckeys[] = self::multicacheKey($this->tableName(), $val); + } + } + + if (!empty($table['primary key'])) { + $fields = $table['primary key']; + $val = array(); + foreach ($fields as $name) { + $val[$name] = self::valueString($this->$name); + } + $ckeys[] = self::multicacheKey($this->tableName(), $val); + } + return $ckeys; + } } \ No newline at end of file diff --git a/classes/User_im_prefs.php b/classes/User_im_prefs.php index cc9dea608d..90df216c54 100644 --- a/classes/User_im_prefs.php +++ b/classes/User_im_prefs.php @@ -80,26 +80,4 @@ class User_im_prefs extends Managed_DataObject ); } - /** - * We have two compound keys with unique constraints: - * (transport, user_id) which is our primary key, and - * (transport, screenname) which is an additional constraint. - * - * Currently there's not a way to represent that second key - * in the general keys list, so we're adding it here to the - * list of keys to use for caching, ensuring that it gets - * cleared as well when we change. - * - * @return array of cache keys - */ - function _allCacheKeys() - { - $ukeys = 'transport,screenname'; - $uvals = $this->transport . ',' . $this->screenname; - - $ckeys = parent::_allCacheKeys(); - $ckeys[] = $this->cacheKey($this->tableName(), $ukeys, $uvals); - return $ckeys; - } - } diff --git a/lib/cache.php b/lib/cache.php index eb4eb66656..59110f74d8 100644 --- a/lib/cache.php +++ b/lib/cache.php @@ -43,11 +43,23 @@ */ class Cache { - var $_items = array(); + /** + * @var array additional in-process cache for web requests; + * disabled on CLI, unsafe for long-running daemons + */ + var $_items = array(); + var $_inlineCache = true; static $_inst = null; const COMPRESSED = 1; + private function __construct() { + // Potentially long-running daemons or maintenance scripts + // should not use an in-process cache as it becomes out of + // date. + $this->_inlineCache = (php_sapi_name() != 'cli'); + } + /** * Singleton constructor * @@ -166,7 +178,7 @@ class Cache common_perf_counter('Cache::get', $key); if (Event::handle('StartCacheGet', array(&$key, &$value))) { - if (array_key_exists($key, $this->_items)) { + if ($this->_inlineCache && array_key_exists($key, $this->_items)) { $value = unserialize($this->_items[$key]); } Event::handle('EndCacheGet', array($key, &$value)); @@ -193,7 +205,9 @@ class Cache if (Event::handle('StartCacheSet', array(&$key, &$value, &$flag, &$expiry, &$success))) { - $this->_items[$key] = serialize($value); + if ($this->_inlineCache) { + $this->_items[$key] = serialize($value); + } $success = true; @@ -244,7 +258,7 @@ class Cache common_perf_counter('Cache::delete', $key); if (Event::handle('StartCacheDelete', array(&$key, &$success))) { - if (array_key_exists($key, $this->_items)) { + if ($this->_inlineCache && array_key_exists($key, $this->_items)) { unset($this->_items[$key]); } $success = true;