PurgeJobUtils.php 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. */
  23. use Wikimedia\Rdbms\IDatabase;
  24. use MediaWiki\MediaWikiServices;
  25. class PurgeJobUtils {
  26. /**
  27. * Invalidate the cache of a list of pages from a single namespace.
  28. * This is intended for use by subclasses.
  29. *
  30. * @param IDatabase $dbw
  31. * @param int $namespace Namespace number
  32. * @param array $dbkeys
  33. */
  34. public static function invalidatePages( IDatabase $dbw, $namespace, array $dbkeys ) {
  35. if ( $dbkeys === [] ) {
  36. return;
  37. }
  38. $fname = __METHOD__;
  39. DeferredUpdates::addUpdate( new AutoCommitUpdate(
  40. $dbw,
  41. __METHOD__,
  42. function () use ( $dbw, $namespace, $dbkeys, $fname ) {
  43. $services = MediaWikiServices::getInstance();
  44. $lbFactory = $services->getDBLoadBalancerFactory();
  45. // Determine which pages need to be updated.
  46. // This is necessary to prevent the job queue from smashing the DB with
  47. // large numbers of concurrent invalidations of the same page.
  48. $now = $dbw->timestamp();
  49. $ids = $dbw->selectFieldValues(
  50. 'page',
  51. 'page_id',
  52. [
  53. 'page_namespace' => $namespace,
  54. 'page_title' => $dbkeys,
  55. 'page_touched < ' . $dbw->addQuotes( $now )
  56. ],
  57. $fname
  58. );
  59. if ( !$ids ) {
  60. return;
  61. }
  62. $batchSize = $services->getMainConfig()->get( 'UpdateRowsPerQuery' );
  63. $ticket = $lbFactory->getEmptyTransactionTicket( $fname );
  64. $idBatches = array_chunk( $ids, $batchSize );
  65. foreach ( $idBatches as $idBatch ) {
  66. $dbw->update(
  67. 'page',
  68. [ 'page_touched' => $now ],
  69. [
  70. 'page_id' => $idBatch,
  71. 'page_touched < ' . $dbw->addQuotes( $now ) // handle races
  72. ],
  73. $fname
  74. );
  75. if ( count( $idBatches ) > 1 ) {
  76. $lbFactory->commitAndWaitForReplication( $fname, $ticket );
  77. }
  78. }
  79. }
  80. ) );
  81. }
  82. }