wiki.techinc.nl/includes/deferred/MWCallableUpdate.php
Timo Tijhof aca3c8203a deferred: Make DeferredUpdates docs more accessible
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
2023-08-25 01:16:17 +01:00

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;
}
}