/**
* @return string Originating method name
*/
- function getOrigin();
+ public function getOrigin();
}
$update->setTransactionTicket( $ticket );
}
- $fnameTrxOwner = get_class( $update ) . '::doUpdate';
+ // Designate $update::doUpdate() as the write round owner
+ $fnameTrxOwner = ( $update instanceof DeferrableCallback )
+ ? $update->getOrigin()
+ : get_class( $update ) . '::doUpdate';
+ // Determine whether the write round will be explicit or implicit
$useExplicitTrxRound = !(
$update instanceof TransactionRoundAwareUpdate &&
$update->getTransactionRoundRequirement() == $update::TRX_ROUND_ABSENT
);
+
// Flush any pending changes left over from an implicit transaction round
if ( $useExplicitTrxRound ) {
$lbFactory->beginMasterChanges( $fnameTrxOwner ); // new explicit round
DeferredUpdates::tryOpportunisticExecute( 'run' );
$this->assertEquals( [ 'oti', 1, 2 ], $calls );
}
+
+ /**
+ * @covers DeferredUpdates::attemptUpdate
+ */
+ public function testCallbackUpdateRounds() {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+
+ $fname = __METHOD__;
+ $called = false;
+ DeferredUpdates::attemptUpdate(
+ new MWCallableUpdate(
+ function () use ( $lbFactory, $fname, &$called ) {
+ $lbFactory->flushReplicaSnapshots( $fname );
+ $lbFactory->commitMasterChanges( $fname );
+ $called = true;
+ },
+ $fname
+ ),
+ $lbFactory
+ );
+
+ $this->assertTrue( $called, "Callback ran" );
+ }
}