1<?php 2/** 3 * Base code for update jobs that put some secondary data extracted 4 * from article content into the database. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * http://www.gnu.org/copyleft/gpl.html 20 * 21 * @file 22 */ 23use MediaWiki\MediaWikiServices; 24use Wikimedia\Rdbms\IDatabase; 25 26class PurgeJobUtils { 27 /** 28 * Invalidate the cache of a list of pages from a single namespace. 29 * This is intended for use by subclasses. 30 * 31 * @param IDatabase $dbw 32 * @param int $namespace Namespace number 33 * @param string[] $dbkeys 34 */ 35 public static function invalidatePages( IDatabase $dbw, $namespace, array $dbkeys ) { 36 if ( $dbkeys === [] ) { 37 return; 38 } 39 $fname = __METHOD__; 40 41 DeferredUpdates::addUpdate( new AutoCommitUpdate( 42 $dbw, 43 __METHOD__, 44 static function () use ( $dbw, $namespace, $dbkeys, $fname ) { 45 $services = MediaWikiServices::getInstance(); 46 $lbFactory = $services->getDBLoadBalancerFactory(); 47 // Determine which pages need to be updated. 48 // This is necessary to prevent the job queue from smashing the DB with 49 // large numbers of concurrent invalidations of the same page. 50 $now = $dbw->timestamp(); 51 $ids = $dbw->selectFieldValues( 52 'page', 53 'page_id', 54 [ 55 'page_namespace' => $namespace, 56 'page_title' => $dbkeys, 57 'page_touched < ' . $dbw->addQuotes( $now ) 58 ], 59 $fname 60 ); 61 62 if ( !$ids ) { 63 return; 64 } 65 66 $batchSize = $services->getMainConfig()->get( 'UpdateRowsPerQuery' ); 67 $ticket = $lbFactory->getEmptyTransactionTicket( $fname ); 68 $idBatches = array_chunk( $ids, $batchSize ); 69 foreach ( $idBatches as $idBatch ) { 70 $dbw->update( 71 'page', 72 [ 'page_touched' => $now ], 73 [ 74 'page_id' => $idBatch, 75 'page_touched < ' . $dbw->addQuotes( $now ) // handle races 76 ], 77 $fname 78 ); 79 if ( count( $idBatches ) > 1 ) { 80 $lbFactory->commitAndWaitForReplication( $fname, $ticket ); 81 } 82 } 83 } 84 ) ); 85 } 86} 87