purgeList.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. /**
  3. * Send purge requests for listed pages to squid
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. * @file
  21. * @ingroup Maintenance
  22. */
  23. require_once __DIR__ . '/Maintenance.php';
  24. /**
  25. * Maintenance script that sends purge requests for listed pages to squid.
  26. *
  27. * @ingroup Maintenance
  28. */
  29. class PurgeList extends Maintenance {
  30. public function __construct() {
  31. parent::__construct();
  32. $this->addDescription( 'Send purge requests for listed pages to squid' );
  33. $this->addOption( 'purge', 'Whether to update page_touched.', false, false );
  34. $this->addOption( 'namespace', 'Namespace number', false, true );
  35. $this->addOption( 'all', 'Purge all pages', false, false );
  36. $this->addOption( 'delay', 'Number of seconds to delay between each purge', false, true );
  37. $this->addOption( 'verbose', 'Show more output', false, false, 'v' );
  38. $this->setBatchSize( 100 );
  39. }
  40. public function execute() {
  41. if ( $this->hasOption( 'all' ) ) {
  42. $this->purgeNamespace( false );
  43. } elseif ( $this->hasOption( 'namespace' ) ) {
  44. $this->purgeNamespace( intval( $this->getOption( 'namespace' ) ) );
  45. } else {
  46. $this->doPurge();
  47. }
  48. $this->output( "Done!\n" );
  49. }
  50. /**
  51. * Purge URL coming from stdin
  52. */
  53. private function doPurge() {
  54. $stdin = $this->getStdin();
  55. $urls = [];
  56. while ( !feof( $stdin ) ) {
  57. $page = trim( fgets( $stdin ) );
  58. if ( preg_match( '%^https?://%', $page ) ) {
  59. $urls[] = $page;
  60. } elseif ( $page !== '' ) {
  61. $title = Title::newFromText( $page );
  62. if ( $title ) {
  63. $url = $title->getInternalURL();
  64. $this->output( "$url\n" );
  65. $urls[] = $url;
  66. if ( $this->getOption( 'purge' ) ) {
  67. $title->invalidateCache();
  68. }
  69. } else {
  70. $this->output( "(Invalid title '$page')\n" );
  71. }
  72. }
  73. }
  74. $this->output( "Purging " . count( $urls ) . " urls\n" );
  75. $this->sendPurgeRequest( $urls );
  76. }
  77. /**
  78. * Purge a namespace or all pages
  79. *
  80. * @param int|bool $namespace
  81. */
  82. private function purgeNamespace( $namespace = false ) {
  83. $dbr = $this->getDB( DB_SLAVE );
  84. $startId = 0;
  85. if ( $namespace === false ) {
  86. $conds = [];
  87. } else {
  88. $conds = [ 'page_namespace' => $namespace ];
  89. }
  90. while ( true ) {
  91. $res = $dbr->select( 'page',
  92. [ 'page_id', 'page_namespace', 'page_title' ],
  93. $conds + [ 'page_id > ' . $dbr->addQuotes( $startId ) ],
  94. __METHOD__,
  95. [
  96. 'LIMIT' => $this->mBatchSize,
  97. 'ORDER BY' => 'page_id'
  98. ]
  99. );
  100. if ( !$res->numRows() ) {
  101. break;
  102. }
  103. $urls = [];
  104. foreach ( $res as $row ) {
  105. $title = Title::makeTitle( $row->page_namespace, $row->page_title );
  106. $url = $title->getInternalURL();
  107. $urls[] = $url;
  108. $startId = $row->page_id;
  109. }
  110. $this->sendPurgeRequest( $urls );
  111. }
  112. }
  113. /**
  114. * Helper to purge an array of $urls
  115. * @param array $urls List of URLS to purge from squids
  116. */
  117. private function sendPurgeRequest( $urls ) {
  118. if ( $this->hasOption( 'delay' ) ) {
  119. $delay = floatval( $this->getOption( 'delay' ) );
  120. foreach ( $urls as $url ) {
  121. if ( $this->hasOption( 'verbose' ) ) {
  122. $this->output( $url . "\n" );
  123. }
  124. $u = new CdnCacheUpdate( [ $url ] );
  125. $u->doUpdate();
  126. usleep( $delay * 1e6 );
  127. }
  128. } else {
  129. if ( $this->hasOption( 'verbose' ) ) {
  130. $this->output( implode( "\n", $urls ) . "\n" );
  131. }
  132. $u = new CdnCacheUpdate( $urls );
  133. $u->doUpdate();
  134. }
  135. }
  136. }
  137. $maintClass = "PurgeList";
  138. require_once RUN_MAINTENANCE_IF_MAIN;