MediaWiki REL1_39
DeferredUpdates Class Reference

Class for managing the deferral of updates within the scope of a PHP script invocation. More...

Static Public Member Functions

static addCallableUpdate ( $callable, $stage=self::POSTSEND, $dbw=null)
 Add an update to the pending update queue that invokes the specified callback when run.
 
static addUpdate (DeferrableUpdate $update, $stage=self::POSTSEND)
 Add an update to the pending update queue for execution at the appropriate time.
 
static attemptUpdate (DeferrableUpdate $update, ILBFactory $lbFactory)
 Attempt to run an update with the appropriate transaction round state it expects.
 
static clearPendingUpdates ()
 Cancel all pending updates for the current execution context.
 
static doUpdates ( $unused=null, $stage=self::ALL)
 Consume and execute all pending updates.
 
static getPendingUpdates ( $stage=self::ALL)
 Get a list of the pending updates for the current execution context.
 
static getRecursiveExecutionStackDepth ()
 Get the number of in-progress calls to DeferredUpdates::doUpdates()
 
static pendingUpdatesCount ()
 Get the number of pending updates for the current execution context.
 
static preventOpportunisticUpdates ()
 Prevent opportunistic updates until the returned ScopedCallback is consumed.
 
static tryOpportunisticExecute ()
 Consume and execute all pending updates unless an update is already in progress or the ILBFactory service instance has "busy" DB handles.
 

Detailed Description

Class for managing the deferral of updates within the scope of a PHP script invocation.

In web request mode, deferred updates run at the end of request execution, after the main database transaction round ends, and either before (PRESEND) or after (POSTSEND) the HTTP response has been sent. If an update runs after the HTTP response is sent, it will not block clients. Otherwise, the client will not see the response until the update finishes. Use the PRESEND and POSTSEND class constants to specify when an update should run. POSTSEND is the default for DeferredUpdates::addUpdate() and DeferredUpdates::addCallableUpdate(). An update that might need to alter the HTTP response output must use PRESEND. The control flow with regard to deferred updates during a typical state changing web request is as follows:

  • 1) Main transaction round starts
  • 2) Various writes to RBMS/file/blob stores and deferred updates enqueued
  • 3) Main transaction round ends
  • 4) PRESEND pending update queue is B1...BN
  • 5) B1 runs, resulting PRESEND updates iteratively run in FIFO order; likewise for B2..BN
  • 6) The web response is sent out to the client
  • 7) POSTSEND pending update queue is A1...AM
  • 8) A1 runs, resulting updates iteratively run in FIFO order; likewise for A2..AM
See also
MediaWiki::restInPeace()

In CLI mode, no distinction is made between PRESEND and POSTSEND deferred updates and all of them will run during the following occasions:

  • a) During DeferredUpdates::addUpdate() if no LBFactory DB handles have writes pending
  • b) On commit of an LBFactory DB handle if no other such handles have writes pending
  • c) During an LBFactory::waitForReplication call if no LBFactory DBs have writes pending
  • d) When the queue is large and an LBFactory DB handle commits (EnqueueableDataUpdate only)
  • e) Upon the completion of Maintenance::execute() via Maintenance::shutdown()
See also
MWLBFactory::applyGlobalState()

If DeferredUpdates::doUpdates() is currently running a deferred update, then the public DeferredUpdates interface operates on the PRESEND/POSTSEND "sub"-queues that correspond to the innermost in-progress deferred update. Otherwise, the public interface operates on the PRESEND/POSTSEND "top"-queues. Affected methods include:

  • DeferredUpdates::addUpdate()
  • DeferredUpdates::addCallableUpdate()
  • DeferredUpdates::doUpdates()
  • DeferredUpdates::tryOpportunisticExecute()
  • DeferredUpdates::pendingUpdatesCount()
  • DeferredUpdates::getPendingUpdates()
  • DeferredUpdates::clearPendingUpdates()

Updates that work through this system will be more likely to complete by the time the client makes their next request after this request than with the JobQueue system.

Since
1.19

Definition at line 82 of file DeferredUpdates.php.

Member Function Documentation

◆ addCallableUpdate()

static DeferredUpdates::addCallableUpdate ( $callable,
$stage = self::POSTSEND,
$dbw = null )
static

Add an update to the pending update queue that invokes the specified callback when run.

See also
DeferredUpdates::addUpdate()
MWCallableUpdate::__construct()
Parameters
callable$callable
int$stageOne of (DeferredUpdates::PRESEND, DeferredUpdates::POSTSEND)
IDatabase | IDatabase[] | null$dbwAbort if this DB is rolled back [optional]
Since
1.27 Added $stage parameter
1.28 Added the $dbw parameter

Definition at line 150 of file DeferredUpdates.php.

References wfGetCaller().

◆ addUpdate()

static DeferredUpdates::addUpdate ( DeferrableUpdate $update,
$stage = self::POSTSEND )
static

Add an update to the pending update queue for execution at the appropriate time.

In CLI mode, callback magic will also be used to run updates when safe

If an update is already in progress, then what happens to this update is as follows:

  • If it has a "defer until" stage at/before the actual run stage of the innermost in-progress update, then it will go into the sub-queue of that in-progress update. As soon as that update completes, MergeableUpdate instances in its sub-queue will be merged into the top-queues and the non-MergeableUpdate instances will be executed. This is done to better isolate updates from the failures of other updates and reduce the chance of race conditions caused by updates not fully seeing the intended changes of previously enqueued and executed updates.
  • If it has a "defer until" stage later than the actual run stage of the innermost in-progress update, then it will go into the normal top-queue for that stage.
Parameters
DeferrableUpdate$updateSome object that implements doUpdate()
int$stageOne of (DeferredUpdates::PRESEND, DeferredUpdates::POSTSEND)
Since
1.28 Added the $stage parameter

Definition at line 124 of file DeferredUpdates.php.

◆ attemptUpdate()

static DeferredUpdates::attemptUpdate ( DeferrableUpdate $update,
ILBFactory $lbFactory )
static

Attempt to run an update with the appropriate transaction round state it expects.

DeferredUpdate classes that wrap the execution of bundles of other DeferredUpdate instances can use this method to run the updates. Any such wrapper class should always use TRX_ROUND_ABSENT itself.

Parameters
DeferrableUpdate$update
ILBFactory$lbFactory
Since
1.34

Definition at line 447 of file DeferredUpdates.php.

References Wikimedia\Rdbms\ILBFactory\beginPrimaryChanges(), Wikimedia\Rdbms\ILBFactory\commitPrimaryChanges(), DeferrableUpdate\doUpdate(), Wikimedia\Rdbms\ILBFactory\getEmptyTransactionTicket(), and Wikimedia\Rdbms\ILBFactory\hasTransactionRound().

◆ clearPendingUpdates()

static DeferredUpdates::clearPendingUpdates ( )
static

Cancel all pending updates for the current execution context.

If an update is in progress, then this operates on the sub-queues of the innermost in-progress update. Otherwise, it acts on the top-queues.

Access: internal
This method should only be used for unit tests

Definition at line 355 of file DeferredUpdates.php.

◆ doUpdates()

static DeferredUpdates::doUpdates ( $unused = null,
$stage = self::ALL )
static

Consume and execute all pending updates.

Note that it is rarely the case that this method should be called outside of a few select entry points. For simplicity, that kind of recursion is discouraged. Recursion cannot happen if an explicit transaction round is active, which limits usage to updates with TRX_ROUND_ABSENT that do not leave open an transactions round of their own during the call to this method.

In the less-common case of this being called within an in-progress DeferrableUpdate, this will not see any top-queue updates (since they were consumed and are being run inside an outer execution loop). In that case, it will instead operate on the sub-queue of the innermost in-progress update on the stack.

Access: internal
For use by MediaWiki, Maintenance, JobRunner, JobExecutor
Parameters
string | null$unusedPreviously for an "enqueue" mode
int$stageWhich updates to process. One of (DeferredUpdates::PRESEND, DeferredUpdates::POSTSEND, DeferredUpdates::ALL)

Definition at line 173 of file DeferredUpdates.php.

References DeferredUpdatesScopeStack\ascend(), and DeferredUpdatesScopeStack\descend().

◆ getPendingUpdates()

static DeferredUpdates::getPendingUpdates ( $stage = self::ALL)
static

Get a list of the pending updates for the current execution context.

If an update is in progress, then this operates on the sub-queues of the innermost in-progress update. Otherwise, it acts on the top-queues.

Parameters
int$stageLook for updates with this "defer until" stage. One of (DeferredUpdates::PRESEND, DeferredUpdates::POSTSEND, DeferredUpdates::ALL)
Returns
DeferrableUpdate[]
Access: internal
This method should only be used for unit tests
Since
1.29

Definition at line 343 of file DeferredUpdates.php.

◆ getRecursiveExecutionStackDepth()

static DeferredUpdates::getRecursiveExecutionStackDepth ( )
static

Get the number of in-progress calls to DeferredUpdates::doUpdates()

Returns
int
Access: internal
This method should only be used for unit tests

Definition at line 365 of file DeferredUpdates.php.

Referenced by tryOpportunisticExecute().

◆ pendingUpdatesCount()

static DeferredUpdates::pendingUpdatesCount ( )
static

Get the number of pending updates for the current execution context.

If an update is in progress, then this operates on the sub-queues of the innermost in-progress update. Otherwise, it acts on the top-queues.

Returns
int
Since
1.28

Definition at line 327 of file DeferredUpdates.php.

◆ preventOpportunisticUpdates()

static DeferredUpdates::preventOpportunisticUpdates ( )
static

Prevent opportunistic updates until the returned ScopedCallback is consumed.

Returns
ScopedCallback

Definition at line 311 of file DeferredUpdates.php.

◆ tryOpportunisticExecute()

static DeferredUpdates::tryOpportunisticExecute ( )
static

Consume and execute all pending updates unless an update is already in progress or the ILBFactory service instance has "busy" DB handles.

A DB handle is considered "busy" if it has an unfinished transaction that cannot safely be flushed or the parent ILBFactory instance has an unfinished transaction round that cannot safely be flushed. If the number of pending updates reaches BIG_QUEUE_SIZE and there are still busy DB handles, then EnqueueableDataUpdate updates might be enqueued as jobs. This avoids excessive memory use and risk of losing updates due to failures.

Note that this method operates on updates from all stages and thus should not be called during web requests. It is only intended for long-running Maintenance scripts.

Access: internal
For use by Maintenance
Since
1.28
Returns
bool Whether updates were allowed to run

Definition at line 270 of file DeferredUpdates.php.

References getRecursiveExecutionStackDepth().


The documentation for this class was generated from the following file: