* @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
*
*
* @return Cache cache object
*/
-
static function instance()
{
if (is_null(self::$_inst)) {
*
* @return string full key
*/
-
static function key($extra)
{
$base_key = common_config('cache', 'base');
$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 (StatusNet::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
*
*
* @return string keyized string
*/
-
static function keyize($str)
{
$str = strtolower($str);
*
* @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));
*
* @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;
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.
*
* @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;
*
* @return boolean success flag
*/
-
function reconnect()
{
$success = false;