Merge "Change 'editfont' default preference to 'monospace'"
[lhc/web/wiklou.git] / includes / jobqueue / JobQueueDB.php
index 5e45730..b5f331b 100644 (file)
@@ -18,7 +18,6 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @author Aaron Schulz
  */
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\DBConnRef;
@@ -185,13 +184,23 @@ class JobQueueDB extends JobQueue {
         * @return void
         */
        protected function doBatchPush( array $jobs, $flags ) {
-               DeferredUpdates::addUpdate( new AutoCommitUpdate(
-                       wfGetDB( DB_MASTER ),
-                       __METHOD__,
-                       function ( IDatabase $dbw, $fname ) use ( $jobs, $flags ) {
+               $dbw = $this->getMasterDB();
+               // In general, there will be two cases here:
+               // a) sqlite; DB connection is probably a regular round-aware handle.
+               // If the connection is busy with a transaction, then defer the job writes
+               // until right before the main round commit step. Any errors that bubble
+               // up will rollback the main commit round.
+               // b) mysql/postgres; DB connection is generally a separate CONN_TRX_AUTO handle.
+               // No transaction is active nor will be started by writes, so enqueue the jobs
+               // now so that any errors will show up immediately as the interface expects. Any
+               // errors that bubble up will rollback the main commit round.
+               $fname = __METHOD__;
+               $dbw->onTransactionPreCommitOrIdle(
+                       function () use ( $dbw, $jobs, $flags, $fname ) {
                                $this->doBatchPushInternal( $dbw, $jobs, $flags, $fname );
-                       }
-               ) );
+                       },
+                       $fname
+               );
        }
 
        /**
@@ -766,10 +775,15 @@ class JobQueueDB extends JobQueue {
        protected function getDB( $index ) {
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                $lb = ( $this->cluster !== false )
-                       ? $lbFactory->getExternalLB( $this->cluster, $this->wiki )
+                       ? $lbFactory->getExternalLB( $this->cluster )
                        : $lbFactory->getMainLB( $this->wiki );
 
-               return $lb->getConnectionRef( $index, [], $this->wiki );
+               return ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' )
+                       // Keep a separate connection to avoid contention and deadlocks;
+                       // However, SQLite has the opposite behavior due to DB-level locking.
+                       ? $lb->getConnectionRef( $index, [], $this->wiki, $lb::CONN_TRX_AUTO )
+                       // Jobs insertion will be defered until the PRESEND stage to reduce contention.
+                       : $lb->getConnectionRef( $index, [], $this->wiki );
        }
 
        /**