From 25a44aa3e4fa511d326b373af71762eb7375db7a Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Tue, 22 Sep 2015 11:43:33 -0700 Subject: [PATCH] Added support for enqueueable DataUpdates * Updates can now declare themselves as having enqueueUpdate() as an alternative to doUpdate(). This lets more expensive or slave lag producing updates use the job queue if desired. * Added a $mode flag to DataUpdate::runUpdates() to prefer pushing jobs over calling doUpdate(). * Made page deletions defer deletion updates when possible. Bug: T95501 Change-Id: Ic6f50f92768089ba0fbc223b8d178f5a91512959 --- autoload.php | 1 + includes/deferred/DataUpdate.php | 56 ++++++++++++++++++++++++-------- includes/page/WikiPage.php | 2 +- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/autoload.php b/autoload.php index 4bed0141bf..0c0324371a 100644 --- a/autoload.php +++ b/autoload.php @@ -384,6 +384,7 @@ $wgAutoloadLocalClasses = array( 'EnhancedChangesList' => __DIR__ . '/includes/changes/EnhancedChangesList.php', 'EnotifNotifyJob' => __DIR__ . '/includes/jobqueue/jobs/EnotifNotifyJob.php', 'EnqueueJob' => __DIR__ . '/includes/jobqueue/jobs/EnqueueJob.php', + 'EnqueueableDataUpdate' => __DIR__ . '/includes/deferred/DataUpdate.php', 'EraseArchivedFile' => __DIR__ . '/maintenance/eraseArchivedFile.php', 'ErrorPageError' => __DIR__ . '/includes/exception/ErrorPageError.php', 'EventRelayer' => __DIR__ . '/includes/libs/eventrelayer/EventRelayer.php', diff --git a/includes/deferred/DataUpdate.php b/includes/deferred/DataUpdate.php index ed12c6012e..f5d6845deb 100644 --- a/includes/deferred/DataUpdate.php +++ b/includes/deferred/DataUpdate.php @@ -30,11 +30,8 @@ * subclasses can override the beginTransaction() and commitTransaction() methods. */ abstract class DataUpdate implements DeferrableUpdate { - /** - * Constructor - */ public function __construct() { - # noop + //noop } /** @@ -73,22 +70,23 @@ abstract class DataUpdate implements DeferrableUpdate { * This allows for limited transactional logic across multiple backends for storing * secondary data. * - * @param array $updates A list of DataUpdate instances + * @param DataUpdate[] $updates A list of DataUpdate instances + * @param string $mode Use "enqueue" to use the job queue when possible [Default: run] * @throws Exception|null */ - public static function runUpdates( $updates ) { - if ( empty( $updates ) ) { - return; # nothing to do + public static function runUpdates( array $updates, $mode = 'run' ) { + if ( $mode === 'enqueue' ) { + // When possible, push updates as jobs instead of calling doUpdate() + $updates = self::enqueueUpdates( $updates ); + } + + if ( !count( $updates ) ) { + return; // nothing to do } $open_transactions = array(); $exception = null; - /** - * @var $update DataUpdate - * @var $trans DataUpdate - */ - try { // begin transactions foreach ( $updates as $update ) { @@ -122,4 +120,36 @@ abstract class DataUpdate implements DeferrableUpdate { throw $exception; // rethrow after cleanup } } + + /** + * Enqueue jobs for every DataUpdate that support enqueueUpdate() + * and return the remaining DataUpdate objects (those that do not) + * + * @param DataUpdate[] $updates A list of DataUpdate instances + * @return DataUpdate[] + * @since 1.26 + */ + protected static function enqueueUpdates( array $updates ) { + $remaining = array(); + + foreach ( $updates as $update ) { + if ( $update instanceof EnqueueableDataUpdate ) { + $update->enqueueUpdate(); + } else { + $remaining[] = $update; + } + } + + return $remaining; + } } + +/** + * @since 1.26 + */ +interface EnqueueableDataUpdate { + /** + * Push the update into the job queue + */ + public function enqueueUpdate(); +} \ No newline at end of file diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index d1cec60b9a..c99928a1c7 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -2916,7 +2916,7 @@ class WikiPage implements Page, IDBAccessObject { // remove secondary indexes, etc $updates = $this->getDeletionUpdates( $content ); - DataUpdate::runUpdates( $updates ); + DataUpdate::runUpdates( $updates, 'enqueue' ); // Reparse any pages transcluding this page LinksUpdate::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' ); -- 2.20.1