In prep for the next decoupling commit: * Rephrase introduction to state what its actually for in practice. * Remove mentions of implementation details in favour of inline comments, especially stuff relating to databases. Except for 1 thing, every integration with databases is already fully decoupled. Automatic cancellation on rollback works by having the caller pass on an IDatabase object to addCallableUpdate() for that specific update, which works even if it came from an unknown LBFactory or unknown service containter. Oppertunistic execution is triggered by service wiring, where MWLBFactory takes responsibility for having LBFactory notify the DeferredUpdates singleton; not the other way around. Bug: T265749 Change-Id: I048d22ffe2fa3838d9a5f4aa4128c756185a6b2e
69 lines
1.7 KiB
PHP
69 lines
1.7 KiB
PHP
<?php
|
|
|
|
use Wikimedia\Rdbms\IDatabase;
|
|
|
|
/**
|
|
* DeferrableUpdate for closure/callable
|
|
*
|
|
* @internal Use DeferredUpdates::addCallableUpdate instead
|
|
*/
|
|
class MWCallableUpdate
|
|
implements DeferrableUpdate, DeferrableCallback, TransactionRoundAwareUpdate
|
|
{
|
|
/** @var callable|null Callback, or null if it was cancelled */
|
|
private $callback;
|
|
/** @var string Calling method name */
|
|
private $fname;
|
|
/** @var int One of the class TRX_ROUND_* constants */
|
|
private $trxRoundRequirement = self::TRX_ROUND_PRESENT;
|
|
|
|
/**
|
|
* @param callable $callback
|
|
* @param string $fname Calling method
|
|
* @param IDatabase|IDatabase[]|null $dbws Cancel the update if a DB transaction
|
|
* is rolled back [optional] (since 1.28)
|
|
*/
|
|
public function __construct( callable $callback, $fname = 'unknown', $dbws = [] ) {
|
|
$this->callback = $callback;
|
|
$this->fname = $fname;
|
|
|
|
$dbws = is_array( $dbws ) ? $dbws : [ $dbws ];
|
|
foreach ( $dbws as $dbw ) {
|
|
if ( $dbw && $dbw->trxLevel() ) {
|
|
$dbw->onTransactionResolution( [ $this, 'cancelOnRollback' ], $fname );
|
|
}
|
|
}
|
|
}
|
|
|
|
public function doUpdate() {
|
|
if ( $this->callback ) {
|
|
call_user_func( $this->callback );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal This method is public so that it works with onTransactionResolution()
|
|
* @param int $trigger
|
|
*/
|
|
public function cancelOnRollback( $trigger ) {
|
|
if ( $trigger === IDatabase::TRIGGER_ROLLBACK ) {
|
|
$this->callback = null;
|
|
}
|
|
}
|
|
|
|
public function getOrigin() {
|
|
return $this->fname;
|
|
}
|
|
|
|
/**
|
|
* @since 1.34
|
|
* @param int $mode One of the class TRX_ROUND_* constants
|
|
*/
|
|
public function setTransactionRoundRequirement( $mode ) {
|
|
$this->trxRoundRequirement = $mode;
|
|
}
|
|
|
|
public function getTransactionRoundRequirement() {
|
|
return $this->trxRoundRequirement;
|
|
}
|
|
}
|