diff options
Diffstat (limited to 'includes/deferred/DeferredUpdates.php')
-rw-r--r-- | includes/deferred/DeferredUpdates.php | 68 |
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(); } } |