From 70b012c595c5ba6f33f17bd3b8e0106345621cab Mon Sep 17 00:00:00 2001 From: bsitu Date: Tue, 19 Aug 2014 15:23:05 -0700 Subject: [PATCH] Add support for adding deferred update within a deferred update Under some configurations all Echo notifications are inserted via a DeferredUpdate. When an extension delays its own notification trigger via DeferredUpdate as well the Echo notification will not be run. Change-Id: Ib40fcd4939ede5b0ff986ab109432630efd1be74 --- includes/deferred/DeferredUpdates.php | 32 +++++++++------- .../includes/deferred/DeferredUpdatesTest.php | 38 +++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 tests/phpunit/includes/deferred/DeferredUpdatesTest.php diff --git a/includes/deferred/DeferredUpdates.php b/includes/deferred/DeferredUpdates.php index 2178281c17..b0c1899f78 100644 --- a/includes/deferred/DeferredUpdates.php +++ b/includes/deferred/DeferredUpdates.php @@ -99,25 +99,29 @@ class DeferredUpdates { $dbw = wfGetDB( DB_MASTER ); } - /** @var DeferrableUpdate $update */ - foreach ( $updates as $update ) { - try { - $update->doUpdate(); + while ( $updates ) { + self::clearPendingUpdates(); - if ( $doCommit && $dbw->trxLevel() ) { - $dbw->commit( __METHOD__, 'flush' ); - } - } catch ( MWException $e ) { - // We don't want exceptions thrown during deferred updates to - // be reported to the user since the output is already sent. - // Instead we just log them. - if ( !$e instanceof ErrorPageError ) { - MWExceptionHandler::logException( $e ); + /** @var DeferrableUpdate $update */ + foreach ( $updates as $update ) { + try { + $update->doUpdate(); + + if ( $doCommit && $dbw->trxLevel() ) { + $dbw->commit( __METHOD__, 'flush' ); + } + } catch ( MWException $e ) { + // We don't want exceptions thrown during deferred updates to + // be reported to the user since the output is already sent. + // Instead we just log them. + if ( !$e instanceof ErrorPageError ) { + MWExceptionHandler::logException( $e ); + } } } + $updates = array_merge( $wgDeferredUpdateList, self::$updates ); } - self::clearPendingUpdates(); wfProfileOut( __METHOD__ ); } diff --git a/tests/phpunit/includes/deferred/DeferredUpdatesTest.php b/tests/phpunit/includes/deferred/DeferredUpdatesTest.php new file mode 100644 index 0000000000..b3d57e796a --- /dev/null +++ b/tests/phpunit/includes/deferred/DeferredUpdatesTest.php @@ -0,0 +1,38 @@ + 'deferred update 1', + '2' => 'deferred update 2', + '3' => 'deferred update 3', + '2-1' => 'deferred update 1 within deferred update 2', + ); + DeferredUpdates::addCallableUpdate( + function () use ( $updates ) { + echo $updates['1']; + } + ); + DeferredUpdates::addCallableUpdate( + function () use ( $updates ) { + echo $updates['2']; + DeferredUpdates::addCallableUpdate( + function() use ( $updates ) { + echo $updates['2-1']; + } + ); + } + ); + DeferredUpdates::addCallableUpdate( + function () use ( $updates ) { + echo $updates[3]; + } + ); + + $this->expectOutputString( implode( '', $updates ) ); + + DeferredUpdates::doUpdates(); + } + +} -- 2.20.1