Merge "IcuCollation: Update comments on $tailoringFirstLetters"
[lhc/web/wiklou.git] / includes / WatchedItemStore.php
index 6486955..9a74401 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
-use MediaWiki\MediaWikiServices;
 use MediaWiki\Linker\LinkTarget;
 use Wikimedia\Assert\Assert;
 
@@ -81,14 +80,12 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return ScopedCallback to reset the overridden value
         * @throws MWException
         */
-       public function overrideDeferredUpdatesAddCallableUpdateCallback( $callback ) {
+       public function overrideDeferredUpdatesAddCallableUpdateCallback( callable $callback ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
                        throw new MWException(
                                'Cannot override DeferredUpdates::addCallableUpdate callback in operation.'
                        );
                }
-               Assert::parameterType( 'callable', $callback, '$callback' );
-
                $previousValue = $this->deferredUpdatesAddCallableUpdateCallback;
                $this->deferredUpdatesAddCallableUpdateCallback = $callback;
                return new ScopedCallback( function() use ( $previousValue ) {
@@ -106,14 +103,12 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return ScopedCallback to reset the overridden value
         * @throws MWException
         */
-       public function overrideRevisionGetTimestampFromIdCallback( $callback ) {
+       public function overrideRevisionGetTimestampFromIdCallback( callable $callback ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
                        throw new MWException(
                                'Cannot override Revision::getTimestampFromId callback in operation.'
                        );
                }
-               Assert::parameterType( 'callable', $callback, '$callback' );
-
                $previousValue = $this->revisionGetTimestampFromIdCallback;
                $this->revisionGetTimestampFromIdCallback = $callback;
                return new ScopedCallback( function() use ( $previousValue ) {
@@ -195,13 +190,13 @@ class WatchedItemStore implements StatsdAwareInterface {
        }
 
        /**
-        * @param int $slaveOrMaster DB_MASTER or DB_SLAVE
+        * @param int $dbIndex DB_MASTER or DB_REPLICA
         *
         * @return DatabaseBase
         * @throws MWException
         */
-       private function getConnection( $slaveOrMaster ) {
-               return $this->loadBalancer->getConnection( $slaveOrMaster, [ 'watchlist' ] );
+       private function getConnection( $dbIndex ) {
+               return $this->loadBalancer->getConnection( $dbIndex, [ 'watchlist' ] );
        }
 
        /**
@@ -222,7 +217,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int
         */
        public function countWatchedItems( User $user ) {
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
                $return = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -242,7 +237,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int
         */
        public function countWatchers( LinkTarget $target ) {
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
                $return = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -268,7 +263,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @throws MWException
         */
        public function countVisitingWatchers( LinkTarget $target, $threshold ) {
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
                $visitingWatchers = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -298,7 +293,7 @@ class WatchedItemStore implements StatsdAwareInterface {
        public function countWatchersMultiple( array $targets, array $options = [] ) {
                $dbOptions = [ 'GROUP BY' => [ 'wl_namespace', 'wl_title' ] ];
 
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
 
                if ( array_key_exists( 'minimumWatchers', $options ) ) {
                        $dbOptions['HAVING'] = 'COUNT(*) >= ' . (int)$options['minimumWatchers'];
@@ -346,7 +341,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                array $targetsWithVisitThresholds,
                $minimumWatchers = null
        ) {
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
 
                $conds = $this->getVisitingWatchersCondition( $dbr, $targetsWithVisitThresholds );
 
@@ -457,7 +452,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return false;
                }
 
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
                $row = $dbr->selectRow(
                        'watchlist',
                        'wl_notificationtimestamp',
@@ -504,7 +499,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                                "wl_title {$options['sort']}"
                        ];
                }
-               $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_SLAVE );
+               $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
 
                $res = $db->select(
                        'watchlist',
@@ -574,7 +569,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return $timestamps;
                }
 
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
 
                $lb = new LinkBatch( $targetsToLoad );
                $res = $dbr->select(
@@ -724,28 +719,31 @@ class WatchedItemStore implements StatsdAwareInterface {
         */
        public function updateNotificationTimestamp( User $editor, LinkTarget $target, $timestamp ) {
                $dbw = $this->getConnection( DB_MASTER );
-               $res = $dbw->select( [ 'watchlist' ],
-                       [ 'wl_user' ],
+               $uids = $dbw->selectFieldValues(
+                       'watchlist',
+                       'wl_user',
                        [
                                'wl_user != ' . intval( $editor->getId() ),
                                'wl_namespace' => $target->getNamespace(),
                                'wl_title' => $target->getDBkey(),
                                'wl_notificationtimestamp IS NULL',
-                       ], __METHOD__
+                       ],
+                       __METHOD__
                );
+               $this->reuseConnection( $dbw );
 
-               $watchers = [];
-               foreach ( $res as $row ) {
-                       $watchers[] = intval( $row->wl_user );
-               }
-
+               $watchers = array_map( 'intval', $uids );
                if ( $watchers ) {
                        // Update wl_notificationtimestamp for all watching users except the editor
                        $fname = __METHOD__;
-                       $dbw->onTransactionIdle(
-                               function () use ( $dbw, $timestamp, $watchers, $target, $fname ) {
+                       DeferredUpdates::addCallableUpdate(
+                               function () use ( $timestamp, $watchers, $target, $fname ) {
                                        global $wgUpdateRowsPerQuery;
 
+                                       $dbw = $this->getConnection( DB_MASTER );
+                                       $factory = wfGetLBFactory();
+                                       $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
+
                                        $watchersChunks = array_chunk( $watchers, $wgUpdateRowsPerQuery );
                                        foreach ( $watchersChunks as $watchersChunk ) {
                                                $dbw->update( 'watchlist',
@@ -758,17 +756,20 @@ class WatchedItemStore implements StatsdAwareInterface {
                                                        ], $fname
                                                );
                                                if ( count( $watchersChunks ) > 1 ) {
-                                                       $dbw->commit( __METHOD__, 'flush' );
-                                                       wfGetLBFactory()->waitForReplication( [ 'wiki' => $dbw->getWikiID() ] );
+                                                       $factory->commitAndWaitForReplication(
+                                                               __METHOD__, $ticket, [ 'wiki' => $dbw->getWikiID() ]
+                                                       );
                                                }
                                        }
                                        $this->uncacheLinkTarget( $target );
-                               }
+
+                                       $this->reuseConnection( $dbw );
+                               },
+                               DeferredUpdates::POSTSEND,
+                               $dbw
                        );
                }
 
-               $this->reuseConnection( $dbw );
-
                return $watchers;
        }
 
@@ -884,7 +885,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $queryOptions['LIMIT'] = $unreadLimit;
                }
 
-               $dbr = $this->getConnection( DB_SLAVE );
+               $dbr = $this->getConnection( DB_REPLICA );
                $rowCount = $dbr->selectRowCount(
                        'watchlist',
                        '1',