&& !$this->manager->getAuthenticationSessionData( 'no-email' )
) {
// TODO show 'confirmemail_oncreate'/'confirmemail_sendfailed' message
- wfGetDB( DB_MASTER )->onTransactionIdle(
+ wfGetDB( DB_MASTER )->onTransactionCommitOrIdle(
function () use ( $user ) {
$user = $user->getInstanceForUpdate();
$status = $user->sendConfirmationMail();
if ( $sendMail ) {
// Send email after DB commit
- $dbw->onTransactionIdle(
+ $dbw->onTransactionCommitOrIdle(
function () use ( $req ) {
/** @var TemporaryPasswordAuthenticationRequest $req */
$this->sendPasswordResetEmail( $req );
if ( $mailpassword ) {
// Send email after DB commit
- wfGetDB( DB_MASTER )->onTransactionIdle(
+ wfGetDB( DB_MASTER )->onTransactionCommitOrIdle(
function () use ( $user, $creator, $req ) {
$this->sendNewAccountEmail( $user, $creator, $req->password );
},
) {
// @FIXME: This would be better as an extension hook
// Send emails or email jobs once this row is safely committed
- $dbw->onTransactionIdle(
+ $dbw->onTransactionCommitOrIdle(
function () use ( $editor, $title ) {
$enotif = new EmailNotification();
$enotif->notifyOnPageChange(
// jobs to become no-ops without any actual jobs that made them redundant.
$dbw = $this->getMasterDB();
$cache = $this->dupCache;
- $dbw->onTransactionIdle(
+ $dbw->onTransactionCommitOrIdle(
function () use ( $cache, $params, $key ) {
$timestamp = $cache->get( $key ); // current last timestamp of this job
if ( $timestamp && $timestamp >= $params['rootJobTimestamp'] ) {
return $this->__call( __FUNCTION__, func_get_args() );
}
+ public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
+ return $this->__call( __FUNCTION__, func_get_args() );
+ }
+
public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
return $this->__call( __FUNCTION__, func_get_args() );
}
$this->trxEndCallbacks[] = [ $callback, $fname, $this->currentAtomicSectionId() ];
}
- final public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
+ final public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
if ( !$this->trxLevel && $this->getTransactionRoundId() ) {
// Start an implicit transaction similar to how query() does
$this->begin( __METHOD__, self::TRANSACTION_INTERNAL );
}
}
+ final public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
+ $this->onTransactionCommitOrIdle( $callback, $fname );
+ }
+
final public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
if ( !$this->trxLevel && $this->getTransactionRoundId() ) {
// Start an implicit transaction similar to how query() does
*
* @param callable $callback
* @param string $fname Caller name
+ * @since 1.32
+ */
+ public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ );
+
+ /**
+ * Alias for onTransactionCommitOrIdle() for backwards-compatibility
+ *
+ * @param callable $callback
+ * @param string $fname
+ * @return mixed
* @since 1.20
+ * @deprecated Since 1.32
*/
public function onTransactionIdle( callable $callback, $fname = __METHOD__ );
*
* Registering a callback here will not affect writesOrCallbacks() pending.
*
- * Since callbacks from this method or onTransactionIdle() can start and end transactions,
+ * Since callbacks from this or onTransactionCommitOrIdle() can start and end transactions,
* a single call to IDatabase::commit might trigger multiple runs of the listener callbacks.
*
* @param string $name Callback name
}
$fname = __METHOD__;
- $dbw->onTransactionIdle( function ( Database $dbw ) use ( $stats, $fname ) {
+ $dbw->onTransactionCommitOrIdle( function ( Database $dbw ) use ( $stats, $fname ) {
$pfhost = $this->perHost ? wfHostname() : '';
// Sqlite: avoid excess b-tree rebuilds (mostly for non-WAL mode)
// non-Sqlite: lower contention with small transactions
$tlCalls = 0;
$lb->beginMasterChanges( __METHOD__ );
$ac = array_fill_keys( [ 'a', 'b', 'c', 'd' ], 0 );
- $conn1->onTransactionIdle( function () use ( &$ac, $conn1, $conn2 ) {
+ $conn1->onTransactionCommitOrIdle( function () use ( &$ac, $conn1, $conn2 ) {
$ac['a'] = 1;
- $conn2->onTransactionIdle( function () use ( &$ac, $conn1, $conn2 ) {
+ $conn2->onTransactionCommitOrIdle( function () use ( &$ac, $conn1, $conn2 ) {
$ac['b'] = 1;
- $conn1->onTransactionIdle( function () use ( &$ac, $conn1, $conn2 ) {
+ $conn1->onTransactionCommitOrIdle( function () use ( &$ac, $conn1, $conn2 ) {
$ac['c'] = 1;
- $conn1->onTransactionIdle( function () use ( &$ac, $conn1, $conn2 ) {
+ $conn1->onTransactionCommitOrIdle( function () use ( &$ac, $conn1, $conn2 ) {
$ac['d'] = 1;
} );
} );
$this->assertEquals( [], $calls );
$dbw = wfGetDB( DB_MASTER );
- $dbw->onTransactionIdle( function () use ( &$calls, $callback2 ) {
+ $dbw->onTransactionCommitOrIdle( function () use ( &$calls, $callback2 ) {
DeferredUpdates::addCallableUpdate( $callback2 );
$this->assertEquals( [], $calls );
$calls[] = 'oti';
$this->assertLastSql( 'BEGIN; ROLLBACK' );
$this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->cancelAtomic( __METHOD__ );
$this->assertLastSql( 'BEGIN; ROLLBACK' );
] ) );
$this->database->startAtomic( __METHOD__ . '_outer' );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
- $this->database->onTransactionIdle( $callback2, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback2, __METHOD__ );
$this->database->cancelAtomic( __METHOD__ );
- $this->database->onTransactionIdle( $callback3, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback3, __METHOD__ );
$this->database->endAtomic( __METHOD__ . '_outer' );
$this->assertLastSql( implode( "; ", [
'BEGIN',
$this->database->startAtomic( __METHOD__ . '_outer' );
$this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
$this->database->startAtomic( __METHOD__ . '_inner' );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->onTransactionPreCommitOrIdle( $callback2, __METHOD__ );
$this->database->onTransactionResolution( $callback3, __METHOD__ );
$this->database->endAtomic( __METHOD__ . '_inner' );
$this->database->startAtomic( __METHOD__ . '_outer' );
$this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
$this->database->startAtomic( __METHOD__ . '_inner', IDatabase::ATOMIC_CANCELABLE );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->onTransactionPreCommitOrIdle( $callback2, __METHOD__ );
$this->database->onTransactionResolution( $callback3, __METHOD__ );
$this->database->endAtomic( __METHOD__ . '_inner' );
$this->database->startAtomic( __METHOD__ . '_outer' );
$atomicId = $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
$this->database->startAtomic( __METHOD__ . '_inner' );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->onTransactionPreCommitOrIdle( $callback2, __METHOD__ );
$this->database->onTransactionResolution( $callback3, __METHOD__ );
$this->database->cancelAtomic( __METHOD__, $atomicId );
$this->database->startAtomic( __METHOD__ . '_outer' );
$atomicId = $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
$this->database->startAtomic( __METHOD__ . '_inner' );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->onTransactionPreCommitOrIdle( $callback2, __METHOD__ );
$this->database->onTransactionResolution( $callback3, __METHOD__ );
try {
$this->database->startAtomic( __METHOD__ . '_outer' );
$this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
$this->database->startAtomic( __METHOD__ . '_inner' );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->onTransactionPreCommitOrIdle( $callback2, __METHOD__ );
$this->database->onTransactionResolution( $callback3, __METHOD__ );
$this->database->cancelAtomic( __METHOD__ . '_inner' );
$this->database->startAtomic( __METHOD__ . '_outer' );
$this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
$this->database->startAtomic( __METHOD__ . '_inner' );
- $this->database->onTransactionIdle( $callback1, __METHOD__ );
+ $this->database->onTransactionCommitOrIdle( $callback1, __METHOD__ );
$this->database->onTransactionPreCommitOrIdle( $callback2, __METHOD__ );
$this->database->onTransactionResolution( $callback3, __METHOD__ );
$wrapper->trxStatus = Database::STATUS_TRX_ERROR;
public function testPrematureClose1() {
$fname = __METHOD__;
$this->database->begin( __METHOD__ );
- $this->database->onTransactionIdle( function () use ( $fname ) {
+ $this->database->onTransactionCommitOrIdle( function () use ( $fname ) {
$this->database->query( 'SELECT 1', $fname );
} );
$this->database->delete( 'x', [ 'field' => 3 ], __METHOD__ );
try {
$fname = __METHOD__;
$this->database->startAtomic( __METHOD__ );
- $this->database->onTransactionIdle( function () use ( $fname ) {
+ $this->database->onTransactionCommitOrIdle( function () use ( $fname ) {
$this->database->query( 'SELECT 1', $fname );
} );
$this->database->delete( 'x', [ 'field' => 3 ], __METHOD__ );
}
/**
- * @covers Wikimedia\Rdbms\Database::onTransactionIdle
+ * @covers Wikimedia\Rdbms\Database::onTransactionCommitOrIdle
* @covers Wikimedia\Rdbms\Database::runOnTransactionIdleCallbacks
*/
public function testTransactionIdle() {
$flagSet = $db->getFlag( DBO_TRX );
};
- $db->onTransactionIdle( $callback, __METHOD__ );
+ $db->onTransactionCommitOrIdle( $callback, __METHOD__ );
$this->assertTrue( $called, 'Callback reached' );
$this->assertFalse( $flagSet, 'DBO_TRX off in callback' );
$this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX still default' );
$flagSet = null;
$called = false;
$db->startAtomic( __METHOD__ );
- $db->onTransactionIdle( $callback, __METHOD__ );
+ $db->onTransactionCommitOrIdle( $callback, __METHOD__ );
$this->assertFalse( $called, 'Callback not reached during TRX' );
$db->endAtomic( __METHOD__ );
$this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' );
$db->clearFlag( DBO_TRX );
- $db->onTransactionIdle(
+ $db->onTransactionCommitOrIdle(
function ( $trigger, IDatabase $db ) {
$db->setFlag( DBO_TRX );
},
}
/**
- * @covers Wikimedia\Rdbms\Database::onTransactionIdle
+ * @covers Wikimedia\Rdbms\Database::onTransactionCommitOrIdle
* @covers Wikimedia\Rdbms\Database::runOnTransactionIdleCallbacks
*/
public function testTransactionIdle_TRX() {
$flagSet = $db->getFlag( DBO_TRX );
};
- $db->onTransactionIdle( $callback, __METHOD__ );
+ $db->onTransactionCommitOrIdle( $callback, __METHOD__ );
$this->assertTrue( $called, 'Called when idle if DBO_TRX is set' );
$this->assertFalse( $flagSet, 'DBO_TRX off in callback' );
$this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX still default' );
$called = false;
$lbFactory->beginMasterChanges( __METHOD__ );
- $db->onTransactionIdle( $callback, __METHOD__ );
+ $db->onTransactionCommitOrIdle( $callback, __METHOD__ );
$this->assertFalse( $called, 'Not called when lb-transaction is active' );
$lbFactory->commitMasterChanges( __METHOD__ );
$called = false;
$lbFactory->beginMasterChanges( __METHOD__ );
- $db->onTransactionIdle( $callback, __METHOD__ );
+ $db->onTransactionCommitOrIdle( $callback, __METHOD__ );
$this->assertFalse( $called, 'Not called when lb-transaction is active' );
$lbFactory->rollbackMasterChanges( __METHOD__ );