updateSpecialPages.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. /**
  3. * Update for cached special pages.
  4. * Run this script periodically if you have miser mode enabled.
  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. * @ingroup Maintenance
  23. */
  24. require_once __DIR__ . '/Maintenance.php';
  25. /**
  26. * Maintenance script to update cached special pages.
  27. *
  28. * @ingroup Maintenance
  29. */
  30. class UpdateSpecialPages extends Maintenance {
  31. public function __construct() {
  32. parent::__construct();
  33. $this->addOption( 'list', 'List special page names' );
  34. $this->addOption( 'only', 'Only update "page"; case sensitive, ' .
  35. 'check correct case by calling this script with --list. ' .
  36. 'Ex: --only=BrokenRedirects', false, true );
  37. $this->addOption( 'override', 'Also update pages that have updates disabled' );
  38. }
  39. public function execute() {
  40. global $wgQueryCacheLimit, $wgDisableQueryPageUpdate;
  41. $dbw = $this->getDB( DB_MASTER );
  42. $this->doSpecialPageCacheUpdates( $dbw );
  43. foreach ( QueryPage::getPages() as $page ) {
  44. list( $class, $special ) = $page;
  45. $limit = isset( $page[2] ) ? $page[2] : null;
  46. # --list : just show the name of pages
  47. if ( $this->hasOption( 'list' ) ) {
  48. $this->output( "$special [QueryPage]\n" );
  49. continue;
  50. }
  51. if ( !$this->hasOption( 'override' )
  52. && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate )
  53. ) {
  54. $this->output( sprintf( "%-30s [QueryPage] disabled\n", $special ) );
  55. continue;
  56. }
  57. $specialObj = SpecialPageFactory::getPage( $special );
  58. if ( !$specialObj ) {
  59. $this->output( "No such special page: $special\n" );
  60. exit;
  61. }
  62. if ( $specialObj instanceof QueryPage ) {
  63. $queryPage = $specialObj;
  64. } else {
  65. $class = get_class( $specialObj );
  66. $this->error( "$class is not an instance of QueryPage.\n", 1 );
  67. die;
  68. }
  69. if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $queryPage->getName() ) {
  70. $this->output( sprintf( '%-30s [QueryPage] ', $special ) );
  71. if ( $queryPage->isExpensive() ) {
  72. $t1 = microtime( true );
  73. # Do the query
  74. $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit );
  75. $t2 = microtime( true );
  76. if ( $num === false ) {
  77. $this->output( "FAILED: database error\n" );
  78. } else {
  79. $this->output( "got $num rows in " );
  80. $elapsed = $t2 - $t1;
  81. $hours = intval( $elapsed / 3600 );
  82. $minutes = intval( $elapsed % 3600 / 60 );
  83. $seconds = $elapsed - $hours * 3600 - $minutes * 60;
  84. if ( $hours ) {
  85. $this->output( $hours . 'h ' );
  86. }
  87. if ( $minutes ) {
  88. $this->output( $minutes . 'm ' );
  89. }
  90. $this->output( sprintf( "%.2fs\n", $seconds ) );
  91. }
  92. # Reopen any connections that have closed
  93. if ( !wfGetLB()->pingAll() ) {
  94. $this->output( "\n" );
  95. do {
  96. $this->error( "Connection failed, reconnecting in 10 seconds..." );
  97. sleep( 10 );
  98. } while ( !wfGetLB()->pingAll() );
  99. $this->output( "Reconnected\n\n" );
  100. }
  101. # Wait for the slave to catch up
  102. wfWaitForSlaves();
  103. } else {
  104. $this->output( "cheap, skipped\n" );
  105. }
  106. if ( $this->hasOption( 'only' ) ) {
  107. break;
  108. }
  109. }
  110. }
  111. }
  112. public function doSpecialPageCacheUpdates( $dbw ) {
  113. global $wgSpecialPageCacheUpdates;
  114. foreach ( $wgSpecialPageCacheUpdates as $special => $call ) {
  115. # --list : just show the name of pages
  116. if ( $this->hasOption( 'list' ) ) {
  117. $this->output( "$special [callback]\n" );
  118. continue;
  119. }
  120. if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $special ) {
  121. if ( !is_callable( $call ) ) {
  122. $this->error( "Uncallable function $call!" );
  123. continue;
  124. }
  125. $this->output( sprintf( '%-30s [callback] ', $special ) );
  126. $t1 = microtime( true );
  127. call_user_func( $call, $dbw );
  128. $t2 = microtime( true );
  129. $this->output( "completed in " );
  130. $elapsed = $t2 - $t1;
  131. $hours = intval( $elapsed / 3600 );
  132. $minutes = intval( $elapsed % 3600 / 60 );
  133. $seconds = $elapsed - $hours * 3600 - $minutes * 60;
  134. if ( $hours ) {
  135. $this->output( $hours . 'h ' );
  136. }
  137. if ( $minutes ) {
  138. $this->output( $minutes . 'm ' );
  139. }
  140. $this->output( sprintf( "%.2fs\n", $seconds ) );
  141. # Wait for the slave to catch up
  142. wfWaitForSlaves();
  143. }
  144. }
  145. }
  146. }
  147. $maintClass = "UpdateSpecialPages";
  148. require_once RUN_MAINTENANCE_IF_MAIN;