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
This commit is contained in:
Aaron Schulz 2015-09-22 11:43:33 -07:00
parent 21206c8fbe
commit 25a44aa3e4
3 changed files with 45 additions and 14 deletions

View file

@ -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',

View file

@ -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();
}

View file

@ -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' );