MediaWiki  master
DeferredUpdates Class Reference

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

Collaboration diagram for DeferredUpdates:

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. More...
 
static addUpdate (DeferrableUpdate $update, $stage=self::POSTSEND)
 Add an update to the pending update queue for execution at the appropriate time. More...
 
static attemptUpdate (DeferrableUpdate $update, ILBFactory $lbFactory)
 Attempt to run an update with the appropriate transaction round state it expects. More...
 
static clearPendingUpdates ()
 Cancel all pending updates for the current execution context. More...
 
static doUpdates ( $mode='run', $stage=self::ALL)
 Consume and execute all pending updates. More...
 
static getPendingUpdates ( $stage=self::ALL)
 Get a list of the pending updates for the current execution context. More...
 
static getRecursiveExecutionStackDepth ()
 Get the number of in-progress calls to DeferredUpdates::doUpdates() More...
 
static pendingUpdatesCount ()
 Get the number of pending updates for the current execution context. More...
 
static tryOpportunisticExecute ( $mode='run')
 Consume and execute all pending updates unless an update is already in progress or the LBFactory service instance has "busy" DB handles. More...
 

Static Private Member Functions

static areDatabaseTransactionsActive ()
 
static getScopeStack ()
 
static jobify (EnqueueableDataUpdate $update, LBFactory $lbFactory, LoggerInterface $logger, StatsdDataFactoryInterface $stats, $httpMethod)
 Enqueue an update as a job in the job queue system and catch/log any exceptions. More...
 
static run (DeferrableUpdate $update, ILBFactory $lbFactory, LoggerInterface $logger, StatsdDataFactoryInterface $stats, $httpMethod)
 Run an update, and, if an error was thrown, catch/log it and enqueue the update as a job in the job queue system if possible (e.g. More...
 

Static Private Attributes

static DeferredUpdatesScopeStack null $scopeStack
 Queue states based on recursion level. More...
 

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:

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:

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 145 of file DeferredUpdates.php.

References addUpdate(), and wfGetCaller().

Referenced by MediaWiki\User\UserGroupManager\addUserToGroup(), MediaWiki\Auth\AuthManager\autoCreateUser(), MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider\beginPrimaryAuthentication(), SpecialEditWatchlist\cleanupWatchlist(), MediaWiki\Watchlist\WatchlistManager\clearTitleUserNotifications(), FileBackendMultiWrite\doDirectoryOp(), LinksDeletionUpdate\doIncrementalUpdate(), FileBackendMultiWrite\doOperationsInternal(), FileBackendMultiWrite\doQuickOperationsInternal(), MediaWiki\Storage\DerivedPageDataUpdater\doUpdates(), WikiPage\doViewUpdates(), EditPage\edit(), RollbackAction\enableTransactionalTimelimit(), MovePageForm\execute(), ApiRollback\execute(), MediaWiki\Logger\Monolog\BufferHandler\handle(), Category\initialize(), WikiPage\insertRedirect(), LocalFile\maybeUpgradeRow(), ResourceLoader\measureResponseTime(), RecentChange\notifyEdit(), RecentChange\notifyNew(), WikiPage\onArticleEdit(), ManualLogEntry\publish(), WikiPage\purgeInterwikiCheckKey(), MediaWiki\Session\SessionBackend\save(), ResourceLoader\saveModuleDependenciesInternal(), SpecialSearch\saveNamespaces(), MediaWiki\Storage\PageUpdater\saveRevision(), Pingback\schedulePingback(), RevDelList\setVisibility(), WikiPage\updateCategoryCounts(), and WatchedItemStore\updateExpiriesAfterMove().

◆ 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 119 of file DeferredUpdates.php.

References $wgCommandLineMode, getScopeStack(), and tryOpportunisticExecute().

Referenced by addCallableUpdate(), MediaWiki\Auth\AuthManager\autoCreateUser(), MediaWiki\Auth\AuthManager\continueAccountCreation(), LocalFile\deleteFile(), MediaWiki\Storage\PageUpdater\doCreate(), WikiPage\doDeleteUpdates(), MediaWiki\Storage\PageUpdater\doModify(), MediaWiki\Storage\DerivedPageDataUpdater\doSecondaryDataUpdates(), LinksUpdate\doUpdate(), MediaWiki\Storage\PageUpdater\doUpdate(), MediaWiki\Storage\DerivedPageDataUpdater\doUpdates(), SpecialRunJobs\execute(), ChangesListSpecialPage\execute(), LocalFileRestoreBatch\execute(), PasswordReset\execute(), WikiImporter\finishImportPage(), MediaWiki\User\UserEditTracker\incrementUserEditCount(), Title\invalidateCache(), PurgeJobUtils\invalidatePages(), JobQueueGroup\lazyPush(), NamespaceDupes\mergePage(), LocalFile\move(), MovePage\moveUnsafe(), MediaWiki\Block\DatabaseBlockStore\purgeExpiredBlocks(), Title\purgeExpiredRestrictions(), HtmlCacheUpdater\purgeTitleUrls(), HtmlCacheUpdater\purgeUrls(), LocalFile\recordUpload3(), MessageCache\replace(), and MediaWiki\schedulePostSendJobs().

◆ areDatabaseTransactionsActive()

static DeferredUpdates::areDatabaseTransactionsActive ( )
staticprivate
Returns
bool If a transaction round is active or connection is not ready for commit()

Definition at line 523 of file DeferredUpdates.php.

References Wikimedia\Rdbms\IDatabase\explicitTrxActive(), Wikimedia\Rdbms\LoadBalancer\forEachOpenMasterConnection(), and Wikimedia\Rdbms\IDatabase\writesOrCallbacksPending().

◆ 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 488 of file DeferredUpdates.php.

References Wikimedia\Rdbms\ILBFactory\beginMasterChanges(), Wikimedia\Rdbms\ILBFactory\commitMasterChanges(), DeferrableUpdate\doUpdate(), Wikimedia\Rdbms\ILBFactory\getEmptyTransactionTicket(), and Wikimedia\Rdbms\ILBFactory\hasTransactionRound().

Referenced by MediaWiki\Storage\DerivedPageDataUpdater\doSecondaryDataUpdates(), RefreshSecondaryDataUpdate\doUpdate(), and run().

◆ 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 350 of file DeferredUpdates.php.

References getScopeStack().

◆ doUpdates()

static DeferredUpdates::doUpdates (   $mode = 'run',
  $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.

The $mode parameter determines how the updates are processed. Use "run" to process the updates by running them. Otherwise, use "enqueue" to process the updates by converting the EnqueueableDataUpdate instances to jobs and running the others.

Parameters
string$modeEither "run" or "enqueue" [default: "run"]
int$stageWhich updates to process. One of (DeferredUpdates::PRESEND, DeferredUpdates::POSTSEND, DeferredUpdates::ALL)
Access: internal
For use by MediaWiki, Maintenance, JobRunner, JobExecutor
Since
1.27 Added $stage parameter

Definition at line 173 of file DeferredUpdates.php.

References $scopeStack, DeferredUpdatesScopeStack\ascend(), DeferredUpdatesScopeStack\descend(), RequestContext\getMain(), getScopeStack(), jobify(), and run().

Referenced by JobRunner\doExecuteJob(), RefreshLinks\fixLinksFromArticle(), NamespaceDupes\mergePage(), MediaWiki\preOutputCommit(), MediaWiki\restInPeace(), Maintenance\shutdown(), and tryOpportunisticExecute().

◆ 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 338 of file DeferredUpdates.php.

References getScopeStack().

◆ 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 360 of file DeferredUpdates.php.

References getScopeStack().

◆ getScopeStack()

static DeferredUpdates::getScopeStack ( )
staticprivate

◆ jobify()

static DeferredUpdates::jobify ( EnqueueableDataUpdate  $update,
LBFactory  $lbFactory,
LoggerInterface  $logger,
StatsdDataFactoryInterface  $stats,
  $httpMethod 
)
staticprivate

Enqueue an update as a job in the job queue system and catch/log any exceptions.

Parameters
EnqueueableDataUpdate$update
LBFactory$lbFactory
LoggerInterface$logger
StatsdDataFactoryInterface$stats
string$httpMethod

Definition at line 446 of file DeferredUpdates.php.

References $type, EnqueueableDataUpdate\getAsJobSpecification(), MWExceptionHandler\logException(), Wikimedia\Rdbms\LBFactory\rollbackMasterChanges(), and JobQueueGroup\singleton().

Referenced by doUpdates().

◆ 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 322 of file DeferredUpdates.php.

References getScopeStack().

Referenced by MediaWiki\outputResponsePayload().

◆ run()

static DeferredUpdates::run ( DeferrableUpdate  $update,
ILBFactory  $lbFactory,
LoggerInterface  $logger,
StatsdDataFactoryInterface  $stats,
  $httpMethod 
)
staticprivate

Run an update, and, if an error was thrown, catch/log it and enqueue the update as a job in the job queue system if possible (e.g.

implements EnqueueableDataUpdate)

Parameters
DeferrableUpdate$update
ILBFactory$lbFactory
LoggerInterface$logger
StatsdDataFactoryInterface$stats
string$httpMethod
Returns
Throwable|null

Definition at line 375 of file DeferredUpdates.php.

References $type, attemptUpdate(), MWExceptionHandler\logException(), Wikimedia\Rdbms\ILBFactory\rollbackMasterChanges(), and JobQueueGroup\singleton().

Referenced by doUpdates().

◆ tryOpportunisticExecute()

static DeferredUpdates::tryOpportunisticExecute (   $mode = 'run')
static

Consume and execute all pending updates unless an update is already in progress or the LBFactory 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 LBFactory 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.

The $mode parameter determines how the updates are processed. Use "run" to process the updates by running them. Otherwise, use "enqueue" to process the updates by converting the EnqueueableDataUpdate instances to jobs and running the others.

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.

Parameters
string$modeEither "run" or "enqueue" [default: "run"]
Returns
bool Whether updates were allowed to run
Access: internal
For use by Maintenance
Since
1.28

Definition at line 282 of file DeferredUpdates.php.

References doUpdates(), EnqueueableDataUpdate\getAsJobSpecification(), getScopeStack(), and JobQueueGroup\singleton().

Referenced by addUpdate(), and MWLBFactory\applyGlobalState().

Member Data Documentation

◆ $scopeStack

DeferredUpdatesScopeStack null DeferredUpdates::$scopeStack
staticprivate

Queue states based on recursion level.

Definition at line 84 of file DeferredUpdates.php.

Referenced by doUpdates(), and getScopeStack().


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