/**
* Abstract base class for update jobs that do something with some secondary
* data extracted from article.
- *
- * @note subclasses should NOT start or commit transactions in their doUpdate() method,
- * a transaction will automatically be wrapped around the update. If need be,
- * subclasses can override the beginTransaction() and commitTransaction() methods.
*/
abstract class DataUpdate implements DeferrableUpdate {
/** @var mixed Result from LBFactory::getEmptyTransactionTicket() */
$this->ticket = $ticket;
}
- /**
- * Begin an appropriate transaction, if any.
- * This default implementation does nothing.
- */
- public function beginTransaction() {
- // noop
- }
-
- /**
- * Commit the transaction started via beginTransaction, if any.
- * This default implementation does nothing.
- */
- public function commitTransaction() {
- // noop
- }
-
- /**
- * Abort / roll back the transaction started via beginTransaction, if any.
- * This default implementation does nothing.
- */
- public function rollbackTransaction() {
- // noop
- }
-
/**
* Convenience method, calls doUpdate() on every DataUpdate in the array.
*
- * This methods supports transactions logic by first calling beginTransaction()
- * on all updates in the array, then calling doUpdate() on each, and, if all goes well,
- * then calling commitTransaction() on each update. If an error occurs,
- * rollbackTransaction() will be called on any update object that had beginTransaction()
- * called but not yet commitTransaction().
- *
- * This allows for limited transactional logic across multiple backends for storing
- * secondary data.
- *
- * @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( 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 = [];
- $exception = null;
-
- try {
- // begin transactions
- foreach ( $updates as $update ) {
- $update->beginTransaction();
- $open_transactions[] = $update;
- }
-
- // do work
- foreach ( $updates as $update ) {
- $update->doUpdate();
- }
-
- // commit transactions
- while ( count( $open_transactions ) > 0 ) {
- $trans = array_pop( $open_transactions );
- $trans->commitTransaction();
- }
- } catch ( Exception $ex ) {
- $exception = $ex;
- wfDebug( "Caught exception, will rethrow after rollback: " .
- $ex->getMessage() . "\n" );
- }
-
- // rollback remaining transactions
- while ( count( $open_transactions ) > 0 ) {
- $trans = array_pop( $open_transactions );
- $trans->rollbackTransaction();
- }
-
- if ( $exception ) {
- 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.27
+ * @throws Exception
+ * @deprecated Since 1.28 Use DeferredUpdates::execute()
*/
- protected static function enqueueUpdates( array $updates ) {
- $remaining = [];
-
+ public static function runUpdates( array $updates ) {
foreach ( $updates as $update ) {
- if ( $update instanceof EnqueueableDataUpdate ) {
- $spec = $update->getAsJobSpecification();
- JobQueueGroup::singleton( $spec['wiki'] )->push( $spec['job'] );
- } else {
- $remaining[] = $update;
- }
+ $update->doUpdate();
}
-
- return $remaining;
}
}