Merge "Add more BacklinkJobUtils comments"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 4 Dec 2015 19:24:54 +0000 (19:24 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 4 Dec 2015 19:24:54 +0000 (19:24 +0000)
1  2 
includes/jobqueue/utils/BacklinkJobUtils.php

  /**
   * Class with Backlink related Job helper methods
   *
+  * When an asset changes, a base job can be inserted to update all assets that depend on it.
+  * The base job splits into per-title "leaf" jobs and a "remnant" job to handle the remaining
+  * range of backlinks. This recurs until the remnant job's backlink range is small enough that
+  * only leaf jobs are created from it.
+  *
+  * For example, if templates A and B are edited (at the same time) the queue will have:
+  *     (A base, B base)
+  * When these jobs run, the queue will have per-title and remnant partition jobs:
+  *       (titleX,titleY,titleZ,...,A remnant,titleM,titleN,titleO,...,B remnant)
+  *
+  * This works best when the queue is FIFO, for several reasons:
+  *   - a) Since the remnant jobs are enqueued after the leaf jobs, the slower leaf jobs have to
+  *        get popped prior to the fast remnant jobs. This avoids flooding the queue with leaf jobs
+  *        for every single backlink of widely used assets (which can be millions).
+  *   - b) Other jobs going in the queue still get a chance to run after a widely used asset changes.
+  *        This is due to the large remnant job pushing to the end of the queue with each division.
+  *
+  * The size of the queues used in this manner depend on the number of assets changes and the
+  * number of workers. Also, with FIFO-per-partition queues, the queue size can be somewhat larger,
+  * depending on the number of queue partitions.
+  *
   * @ingroup JobQueue
   * @since 1.23
   */
@@@ -71,7 -92,6 +92,7 @@@ class BacklinkJobUtils 
  
                if ( isset( $params['pages'] ) || empty( $params['recursive'] ) ) {
                        $ranges = array(); // sanity; this is a leaf node
 +                      $realBSize = 0;
                        wfWarn( __METHOD__ . " called on {$job->getType()} leaf job (explosive recursion)." );
                } elseif ( isset( $params['range'] ) ) {
                        // This is a range job to trigger the insertion of partitioned/title jobs...
                // Combine the first range (of size $bSize) backlinks into leaf jobs
                if ( isset( $ranges[0] ) ) {
                        list( $start, $end ) = $ranges[0];
 -                      $titles = $title->getBacklinkCache()->getLinks( $params['table'], $start, $end );
 -                      foreach ( array_chunk( iterator_to_array( $titles ), $cSize ) as $titleBatch ) {
 +                      $iter = $title->getBacklinkCache()->getLinks( $params['table'], $start, $end );
 +                      $titles = iterator_to_array( $iter );
 +                      /** @var Title[] $titleBatch */
 +                      foreach ( array_chunk( $titles, $cSize ) as $titleBatch ) {
                                $pages = array();
                                foreach ( $titleBatch as $tl ) {
                                        $pages[$tl->getArticleId()] = array( $tl->getNamespace(), $tl->getDBKey() );