Inject MultiWriteBagOStuff addCallableUpdate() dependency
Inject the DeferredUpdates::addCallableUpdate method via the ObjectCache. This brings it closer to being able to move to /libs. Change-Id: Ifa0d893002c3d709a4dc7346c263a92162274bd7
This commit is contained in:
parent
442d4cb497
commit
1171cc00cd
3 changed files with 34 additions and 19 deletions
|
|
@ -33,6 +33,8 @@ class MultiWriteBagOStuff extends BagOStuff {
|
|||
protected $caches;
|
||||
/** @var bool Use async secondary writes */
|
||||
protected $asyncWrites = false;
|
||||
/** @var callback|null */
|
||||
protected $asyncHandler;
|
||||
|
||||
/** Idiom for "write to all backends" */
|
||||
const ALL = INF;
|
||||
|
|
@ -48,15 +50,16 @@ class MultiWriteBagOStuff extends BagOStuff {
|
|||
* be read in the fallback chain. Writes happen to all stores
|
||||
* in the order they are defined. However, lock()/unlock() calls
|
||||
* only use the primary store.
|
||||
* - replication: Either 'sync' or 'async'. This controls whether writes to
|
||||
* secondary stores are deferred when possible. Async writes
|
||||
* require the HHVM register_postsend_function() function.
|
||||
* - replication: Either 'sync' or 'async'. This controls whether writes
|
||||
* to secondary stores are deferred when possible. Async writes
|
||||
* require setting 'asyncCallback'. HHVM register_postsend_function() function.
|
||||
* Async writes can increase the chance of some race conditions
|
||||
* or cause keys to expire seconds later than expected. It is
|
||||
* safe to use for modules when cached values: are immutable,
|
||||
* invalidation uses logical TTLs, invalidation uses etag/timestamp
|
||||
* validation against the DB, or merge() is used to handle races.
|
||||
*
|
||||
* - asyncHandler: callable that takes a callback and runs it after the
|
||||
* current web request ends. In CLI mode, it should run it immediately.
|
||||
* @param array $params
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
|
|
@ -85,7 +88,14 @@ class MultiWriteBagOStuff extends BagOStuff {
|
|||
}
|
||||
}
|
||||
|
||||
$this->asyncWrites = isset( $params['replication'] ) && $params['replication'] === 'async';
|
||||
$this->asyncHandler = isset( $params['asyncHandler'] )
|
||||
? $params['asyncHandler']
|
||||
: null;
|
||||
$this->asyncWrites = (
|
||||
isset( $params['replication'] ) &&
|
||||
$params['replication'] === 'async' &&
|
||||
is_callable( $this->asyncHandler )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -226,7 +236,8 @@ class MultiWriteBagOStuff extends BagOStuff {
|
|||
} else {
|
||||
// Secondary write in async mode: do not block this HTTP request
|
||||
$logger = $this->logger;
|
||||
DeferredUpdates::addCallableUpdate(
|
||||
call_user_func(
|
||||
$this->asyncHandler,
|
||||
function () use ( $cache, $method, $args, $logger ) {
|
||||
if ( !call_user_func_array( array( $cache, $method ), $args ) ) {
|
||||
$logger->warning( "Async $method op failed" );
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ class ObjectCache {
|
|||
return call_user_func( $params['factory'], $params );
|
||||
} elseif ( isset( $params['class'] ) ) {
|
||||
$class = $params['class'];
|
||||
if ( $class === 'MultiWriteBagOStuff' && !isset( $params['asyncHandler'] ) ) {
|
||||
$params['asyncHandler'] = 'DeferredUpdates::addCallableUpdate';
|
||||
}
|
||||
return new $class( $params );
|
||||
} else {
|
||||
throw new MWException( "The definition of cache type \""
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ class MultiWriteBagOStuffTest extends MediaWikiTestCase {
|
|||
$this->cache2 = new HashBagOStuff();
|
||||
$this->cache = new MultiWriteBagOStuff( array(
|
||||
'caches' => array( $this->cache1, $this->cache2 ),
|
||||
'replication' => 'async'
|
||||
'replication' => 'async',
|
||||
'asyncHandler' => 'DeferredUpdates::addCallableUpdate'
|
||||
) );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue