diff --git a/README b/README index 6343e3e024..3bebb11ee0 100644 --- a/README +++ b/README @@ -1538,6 +1538,18 @@ external: external links in notices. One of three values: 'sometimes', nofollowed on profile, notice, and favorites page. Default is 'sometimes'. +router +------ + +We use a router class for mapping URLs to code. This section controls +how that router works. + +cache: whether to cache the router in memcache (or another caching + mechanism). Defaults to true, but may be set to false for + developers (who might be actively adding pages, so won't want the + router cached) or others who see strange behavior. You're unlikely + to need this unless you're a developer. + Plugins ======= diff --git a/lib/cache.php b/lib/cache.php index ea0ff769d1..dc667654ab 100644 --- a/lib/cache.php +++ b/lib/cache.php @@ -86,6 +86,55 @@ class Cache return 'statusnet:' . $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)) { + + $plugins = StatusNet::getActivePlugins(); + $names = array(); + + foreach ($plugins as $plugin) { + $names[] = $plugin[0]; + } + + $names = array_unique($names); + asort($names); + + // Unique enough. + + $uniq = crc32(implode(',', $names)); + + $build = common_config('site', 'build'); + + $prefix = STATUSNET_VERSION.':'.$build.':'.$uniq; + } + + return Cache::key($prefix.':'.$extra); + } + /** * Make a string suitable for use as a key * diff --git a/lib/default.php b/lib/default.php index a91fa338fc..029dbb3906 100644 --- a/lib/default.php +++ b/lib/default.php @@ -59,7 +59,8 @@ $default = 'textlimit' => 140, 'indent' => true, 'use_x_sendfile' => false, - 'notice' => null // site wide notice text + 'notice' => null, // site wide notice text + 'build' => 1, // build number, for code-dependent cache ), 'db' => array('database' => 'YOU HAVE TO SET THIS IN config.php', @@ -327,4 +328,6 @@ $default = array('ssl_cafile' => false, // To enable SSL cert validation, point to a CA bundle (eg '/usr/lib/ssl/certs/ca-certificates.crt') 'curl' => false, // Use CURL backend for HTTP fetches if available. (If not, PHP's socket streams will be used.) ), + 'router' => + array('cache' => true), // whether to cache the router object. Defaults to true, turn off for devel ); diff --git a/lib/router.php b/lib/router.php index 8670519ff4..eff88bb462 100644 --- a/lib/router.php +++ b/lib/router.php @@ -127,15 +127,19 @@ class Router function __construct() { if (empty($this->m)) { - $k = self::cacheKey(); - $c = Cache::instance(); - $m = $c->get($k); - if (!empty($m)) { - $this->m = $m; - } else { + if (!common_config('router', 'cache')) { $this->m = $this->initialize(); - $c->set($k, $this->m); - } + } else { + $k = self::cacheKey(); + $c = Cache::instance(); + $m = $c->get($k); + if (!empty($m)) { + $this->m = $m; + } else { + $this->m = $this->initialize(); + $c->set($k, $this->m); + } + } } } @@ -156,21 +160,7 @@ class Router static function cacheKey() { - $plugins = StatusNet::getActivePlugins(); - $names = array(); - - foreach ($plugins as $plugin) { - $names[] = $plugin[0]; - } - - $names = array_unique($names); - asort($names); - - // Unique enough. - - $uniq = crc32(implode(',', $names)); - - return Cache::key('router:'.STATUSNET_VERSION.':'.$uniq); + return Cache::codeKey('router'); } function initialize()