summaryrefslogtreecommitdiff
path: root/includes/deferred/DeferredUpdates.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/deferred/DeferredUpdates.php')
-rw-r--r--includes/deferred/DeferredUpdates.php68
1 files changed, 34 insertions, 34 deletions
diff --git a/includes/deferred/DeferredUpdates.php b/includes/deferred/DeferredUpdates.php
index 42816ddc..cd0266f6 100644
--- a/includes/deferred/DeferredUpdates.php
+++ b/includes/deferred/DeferredUpdates.php
@@ -34,13 +34,18 @@ interface DeferrableUpdate {
}
/**
- * Class for managing the deferred updates.
+ * Class for managing the deferred updates
+ *
+ * Deferred updates can be run at the end of the request,
+ * after the HTTP response has been sent. In CLI mode, updates
+ * are only deferred until there is no local master DB transaction.
+ * When updates are deferred, they go into a simple FIFO queue.
*
* @since 1.19
*/
class DeferredUpdates {
/**
- * Store of updates to be deferred until the end of the request.
+ * @var array Updates to be deferred until the end of the request.
*/
private static $updates = array();
@@ -49,18 +54,28 @@ class DeferredUpdates {
* @param DeferrableUpdate $update Some object that implements doUpdate()
*/
public static function addUpdate( DeferrableUpdate $update ) {
+ global $wgCommandLineMode;
+
array_push( self::$updates, $update );
- }
- /**
- * HTMLCacheUpdates are the most common deferred update people use. This
- * is a shortcut method for that.
- * @see HTMLCacheUpdate::__construct()
- * @param Title $title
- * @param string $table
- */
- public static function addHTMLCacheUpdate( $title, $table ) {
- self::addUpdate( new HTMLCacheUpdate( $title, $table ) );
+ // CLI scripts may forget to periodically flush these updates,
+ // so try to handle that rather than OOMing and losing them.
+ // Try to run the updates as soon as there is no local transaction.
+ static $waitingOnTrx = false; // de-duplicate callback
+ if ( $wgCommandLineMode && !$waitingOnTrx ) {
+ $lb = wfGetLB();
+ $dbw = $lb->getAnyOpenConnection( $lb->getWriterIndex() );
+ // Do the update as soon as there is no transaction
+ if ( $dbw && $dbw->trxLevel() ) {
+ $waitingOnTrx = true;
+ $dbw->onTransactionIdle( function() use ( &$waitingOnTrx ) {
+ DeferredUpdates::doUpdates();
+ $waitingOnTrx = false;
+ } );
+ } else {
+ self::doUpdates();
+ }
+ }
}
/**
@@ -80,23 +95,9 @@ class DeferredUpdates {
* prevent lock contention
*/
public static function doUpdates( $commit = '' ) {
- global $wgDeferredUpdateList;
-
- $updates = array_merge( $wgDeferredUpdateList, self::$updates );
+ $updates = self::$updates;
- // No need to get master connections in case of empty updates array
- if ( !count( $updates ) ) {
-
- return;
- }
-
- $dbw = false;
- $doCommit = $commit == 'commit';
- if ( $doCommit ) {
- $dbw = wfGetDB( DB_MASTER );
- }
-
- while ( $updates ) {
+ while ( count( $updates ) ) {
self::clearPendingUpdates();
/** @var DeferrableUpdate $update */
@@ -104,8 +105,8 @@ class DeferredUpdates {
try {
$update->doUpdate();
- if ( $doCommit && $dbw->trxLevel() ) {
- $dbw->commit( __METHOD__, 'flush' );
+ if ( $commit === 'commit' ) {
+ wfGetLBFactory()->commitMasterChanges();
}
} catch ( Exception $e ) {
// We don't want exceptions thrown during deferred updates to
@@ -116,9 +117,9 @@ class DeferredUpdates {
}
}
}
- $updates = array_merge( $wgDeferredUpdateList, self::$updates );
- }
+ $updates = self::$updates;
+ }
}
/**
@@ -126,7 +127,6 @@ class DeferredUpdates {
* want or need to call this. Unit tests need it though.
*/
public static function clearPendingUpdates() {
- global $wgDeferredUpdateList;
- $wgDeferredUpdateList = self::$updates = array();
+ self::$updates = array();
}
}