X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fcache.php;h=104314cb06b24aee08eb3688b12dd9e7af6c4bce;hb=0715a50e0b6ae08e1f6b24d615566e9031ffd756;hp=df6fc364931fb2f7b0734523e76724b8c8b675d5;hpb=32084e33a266797b306158df29e48f057651b410;p=quix0rs-gnu-social.git diff --git a/lib/cache.php b/lib/cache.php index df6fc36493..104314cb06 100644 --- a/lib/cache.php +++ b/lib/cache.php @@ -41,14 +41,25 @@ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ - 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 * @@ -56,7 +67,6 @@ class Cache * * @return Cache cache object */ - static function instance() { if (is_null(self::$_inst)) { @@ -77,18 +87,64 @@ class Cache * * @return string full key */ - static function key($extra) { $base_key = common_config('cache', 'base'); if (empty($base_key)) { - $base_key = common_keyize(common_config('site', 'name')); + $base_key = self::keyize(common_config('site', 'name')); } - return 'statusnet:' . $base_key . ':' . $extra; + return 'gnusocial:' . $base_key . ':' . $extra; } + /** + * Create a cache key for data dependent on code + * + * For cache elements that are dependent on changes in code, this creates + * a more-or-less fingerprint of the current running code and adds it to + * the cache key. In the case of an upgrade of core, or addition or + * removal of plugins, a new unique fingerprint is generated and used. + * + * There can still be problems with a) differences in versions of the + * plugins and b) people running code between official versions. This is + * usually a problem only for experienced users like developers, who know + * how to clear their cache. + * + * For sites that run code between versions (like the status.net cloud), + * there's an additional build number configuration setting. + * + * @param string $extra the real part of the key + * + * @return string full key + */ + + static function codeKey($extra) + { + static $prefix = null; + + if (empty($prefix)) { + + $names = array(); + + foreach (GNUsocial::getActivePlugins() as $plugin=>$attrs) { + $names[] = $plugin; + } + + asort($names); + + // Unique enough. + + $uniq = crc32(implode(',', $names)); + + $build = common_config('site', 'build'); + + $prefix = GNUSOCIAL_VERSION.':'.$build.':'.$uniq; + } + + return Cache::key($prefix.':'.$extra); + } + /** * Make a string suitable for use as a key * @@ -98,7 +154,6 @@ class Cache * * @return string keyized string */ - static function keyize($str) { $str = strtolower($str); @@ -115,13 +170,13 @@ class Cache * * @return string retrieved value or null if unfound */ - function get($key) { $value = false; + 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)); @@ -140,15 +195,17 @@ class Cache * * @return boolean success flag */ - function set($key, $value, $flag=null, $expiry=null) { $success = false; + common_perf_counter('Cache::set', $key); 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; @@ -159,6 +216,33 @@ class Cache return $success; } + /** + * Atomically increment an existing numeric value. + * Existing expiration time should remain unchanged, if any. + * + * @param string $key The key to use for lookups + * @param int $step Amount to increment (default 1) + * + * @return mixed incremented value, or false if not set. + */ + function increment($key, $step=1) + { + $value = false; + common_perf_counter('Cache::increment', $key); + if (Event::handle('StartCacheIncrement', array(&$key, &$step, &$value))) { + // Fallback is not guaranteed to be atomic, + // and may original expiry value. + $value = $this->get($key); + if ($value !== false) { + $value += $step; + $ok = $this->set($key, $value); + $got = $this->get($key); + } + Event::handle('EndCacheIncrement', array($key, $step, $value)); + } + return $value; + } + /** * Delete the value associated with a key * @@ -166,13 +250,13 @@ class Cache * * @return boolean success flag */ - function delete($key) { $success = false; + 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; @@ -188,7 +272,6 @@ class Cache * * @return boolean success flag */ - function reconnect() { $success = false;