* In SqlBagOStuff, ignore errors due to a read-only database, per my comments on CR r42796. Same for LocalisationCache. * Merged SqlBagOStuff and MediaWikiBagOStuff, that proved to be an awkward and unnecessary generalisation. Use the standard quoting wrapper functions instead of $db->query(). * Implemented atomic incr() and decr() functions for SqlBagOStuff. * Made incr() and decr() generally work roughly the same as it does in memcached, respecting negative steps instead of ignoring such operations. This allows decr() to be implemented in terms of incr(). * Per bug 11533, in MessageCache.php, don't retry 20 times on a cache failure, that's really memcached-specific and won't be useful for other cache types. It's not really very useful for memcached either. * Moved MySQL-specific implementations of wasDeadlock() and wasErrorReissuable() to DatabaseMysql. * Briefly tested page views with $wgReadOnly=read_only=1, fixed an error from Article::viewUpdates(). A CentralAuth fix will be in a subsequent commit.
128 lines
3.8 KiB
PHP
128 lines
3.8 KiB
PHP
<?php
|
|
/**
|
|
* @file
|
|
* @ingroup Cache
|
|
*/
|
|
|
|
/**
|
|
* FakeMemCachedClient imitates the API of memcached-client v. 0.1.2.
|
|
* It acts as a memcached server with no RAM, that is, all objects are
|
|
* cleared the moment they are set. All set operations succeed and all
|
|
* get operations return null.
|
|
* @ingroup Cache
|
|
*/
|
|
class FakeMemCachedClient {
|
|
function add ($key, $val, $exp = 0) { return true; }
|
|
function decr ($key, $amt=1) { return null; }
|
|
function delete ($key, $time = 0) { return false; }
|
|
function disconnect_all () { }
|
|
function enable_compress ($enable) { }
|
|
function forget_dead_hosts () { }
|
|
function get ($key) { return null; }
|
|
function get_multi ($keys) { return array_pad(array(), count($keys), null); }
|
|
function incr ($key, $amt=1) { return null; }
|
|
function replace ($key, $value, $exp=0) { return false; }
|
|
function run_command ($sock, $cmd) { return null; }
|
|
function set ($key, $value, $exp=0){ return true; }
|
|
function set_compress_threshold ($thresh){ }
|
|
function set_debug ($dbg) { }
|
|
function set_servers ($list) { }
|
|
}
|
|
|
|
global $wgCaches;
|
|
$wgCaches = array();
|
|
|
|
/**
|
|
* Get a cache object.
|
|
* @param int $inputType cache type, one the the CACHE_* constants.
|
|
*/
|
|
function &wfGetCache( $inputType ) {
|
|
global $wgCaches, $wgMemCachedServers, $wgMemCachedDebug, $wgMemCachedPersistent;
|
|
$cache = false;
|
|
|
|
if ( $inputType == CACHE_ANYTHING ) {
|
|
reset( $wgCaches );
|
|
$type = key( $wgCaches );
|
|
if ( $type === false || $type === CACHE_NONE ) {
|
|
$type = CACHE_DB;
|
|
}
|
|
} else {
|
|
$type = $inputType;
|
|
}
|
|
|
|
if ( $type == CACHE_MEMCACHED ) {
|
|
if ( !array_key_exists( CACHE_MEMCACHED, $wgCaches ) ) {
|
|
if ( !class_exists( 'MemCachedClientforWiki' ) ) {
|
|
class MemCachedClientforWiki extends memcached {
|
|
function _debugprint( $text ) {
|
|
wfDebug( "memcached: $text" );
|
|
}
|
|
}
|
|
}
|
|
$wgCaches[CACHE_MEMCACHED] = new MemCachedClientforWiki(
|
|
array('persistant' => $wgMemCachedPersistent, 'compress_threshold' => 1500 ) );
|
|
$wgCaches[CACHE_MEMCACHED]->set_servers( $wgMemCachedServers );
|
|
$wgCaches[CACHE_MEMCACHED]->set_debug( $wgMemCachedDebug );
|
|
}
|
|
$cache =& $wgCaches[CACHE_MEMCACHED];
|
|
} elseif ( $type == CACHE_ACCEL ) {
|
|
if ( !array_key_exists( CACHE_ACCEL, $wgCaches ) ) {
|
|
if ( function_exists( 'eaccelerator_get' ) ) {
|
|
$wgCaches[CACHE_ACCEL] = new eAccelBagOStuff;
|
|
} elseif ( function_exists( 'apc_fetch') ) {
|
|
$wgCaches[CACHE_ACCEL] = new APCBagOStuff;
|
|
} elseif( function_exists( 'xcache_get' ) ) {
|
|
$wgCaches[CACHE_ACCEL] = new XCacheBagOStuff();
|
|
} elseif ( function_exists( 'mmcache_get' ) ) {
|
|
$wgCaches[CACHE_ACCEL] = new TurckBagOStuff;
|
|
} else {
|
|
$wgCaches[CACHE_ACCEL] = false;
|
|
}
|
|
}
|
|
if ( $wgCaches[CACHE_ACCEL] !== false ) {
|
|
$cache =& $wgCaches[CACHE_ACCEL];
|
|
}
|
|
} elseif ( $type == CACHE_DBA ) {
|
|
if ( !array_key_exists( CACHE_DBA, $wgCaches ) ) {
|
|
$wgCaches[CACHE_DBA] = new DBABagOStuff;
|
|
}
|
|
$cache =& $wgCaches[CACHE_DBA];
|
|
}
|
|
|
|
if ( $type == CACHE_DB || ( $inputType == CACHE_ANYTHING && $cache === false ) ) {
|
|
if ( !array_key_exists( CACHE_DB, $wgCaches ) ) {
|
|
$wgCaches[CACHE_DB] = new SqlBagOStuff('objectcache');
|
|
}
|
|
$cache =& $wgCaches[CACHE_DB];
|
|
}
|
|
|
|
if ( $cache === false ) {
|
|
if ( !array_key_exists( CACHE_NONE, $wgCaches ) ) {
|
|
$wgCaches[CACHE_NONE] = new FakeMemCachedClient;
|
|
}
|
|
$cache =& $wgCaches[CACHE_NONE];
|
|
}
|
|
|
|
return $cache;
|
|
}
|
|
|
|
/** Get the main cache object */
|
|
function &wfGetMainCache() {
|
|
global $wgMainCacheType;
|
|
$ret =& wfGetCache( $wgMainCacheType );
|
|
return $ret;
|
|
}
|
|
|
|
/** Get the cache object used by the message cache */
|
|
function &wfGetMessageCacheStorage() {
|
|
global $wgMessageCacheType;
|
|
$ret =& wfGetCache( $wgMessageCacheType );
|
|
return $ret;
|
|
}
|
|
|
|
/** Get the cache object used by the parser cache */
|
|
function &wfGetParserCacheStorage() {
|
|
global $wgParserCacheType;
|
|
$ret =& wfGetCache( $wgParserCacheType );
|
|
return $ret;
|
|
}
|