Merge "Reduce lag waiting time in CategoryMembershipUpdateJob critical section"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 21 Nov 2017 19:13:34 +0000 (19:13 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 21 Nov 2017 19:13:34 +0000 (19:13 +0000)
1  2 
includes/jobqueue/jobs/CategoryMembershipChangeJob.php

@@@ -25,8 -25,6 +25,8 @@@ use Wikimedia\Rdbms\LBFactory
  /**
   * Job to add recent change entries mentioning category membership changes
   *
 + * This allows users to easily scan categories for recent page membership changes
 + *
   * Parameters include:
   *   - pageId : page ID
   *   - revTimestamp : timestamp of the triggering revision
@@@ -61,6 -59,13 +61,13 @@@ class CategoryMembershipChangeJob exten
                        return false; // deleted?
                }
  
+               // Cut down on the time spent in safeWaitForMasterPos() in the critical section
+               $dbr = $lb->getConnection( DB_REPLICA, [ 'recentchanges' ] );
+               if ( !$lb->safeWaitForMasterPos( $dbr ) ) {
+                       $this->setLastError( "Timed out while pre-waiting for replica DB to catch up" );
+                       return false;
+               }
                // Use a named lock so that jobs for this page see each others' changes
                $lockKey = "CategoryMembershipUpdates:{$page->getId()}";
                $scopedLock = $dbw->getScopedLockAndFlush( $lockKey, __METHOD__, 3 );
@@@ -69,8 -74,7 +76,7 @@@
                        return false;
                }
  
-               $dbr = $lb->getConnection( DB_REPLICA, [ 'recentchanges' ] );
-               // Wait till the replica DB is caught up so that jobs for this page see each others' changes
+               // Wait till replica DB is caught up so that jobs for this page see each others' changes
                if ( !$lb->safeWaitForMasterPos( $dbr ) ) {
                        $this->setLastError( "Timed out while waiting for replica DB to catch up" );
                        return false;
                // between COMMIT and actual enqueueing of the CategoryMembershipChangeJob job.
                $cutoffUnix -= self::ENQUEUE_FUDGE_SEC;
  
 -              // Get the newest revision that has a SRC_CATEGORIZE row...
 +              // Get the newest page revision that has a SRC_CATEGORIZE row.
 +              // Assume that category changes before it were already handled.
                $row = $dbr->selectRow(
 -                      [ 'revision', 'recentchanges' ],
 +                      'revision',
                        [ 'rev_timestamp', 'rev_id' ],
                        [
                                'rev_page' => $page->getId(),
 -                              'rev_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $cutoffUnix ) )
 -                      ],
 -                      __METHOD__,
 -                      [ 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC' ],
 -                      [
 -                              'recentchanges' => [
 -                                      'INNER JOIN',
 +                              'rev_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $cutoffUnix ) ),
 +                              'EXISTS (' . $dbr->selectSQLText(
 +                                      'recentchanges',
 +                                      '1',
                                        [
                                                'rc_this_oldid = rev_id',
                                                'rc_source' => RecentChange::SRC_CATEGORIZE,
                                                // Allow rc_cur_id or rc_timestamp index usage
                                                'rc_cur_id = rev_page',
 -                                              'rc_timestamp >= rev_timestamp'
 +                                              'rc_timestamp = rev_timestamp'
                                        ]
 -                              ]
 -                      ]
 +                              ) . ')'
 +                      ],
 +                      __METHOD__,
 +                      [ 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC' ]
                );
                // Only consider revisions newer than any such revision
                if ( $row ) {