diff options
Diffstat (limited to 'includes/deferred')
-rw-r--r-- | includes/deferred/DeferredUpdates.php | 6 | ||||
-rw-r--r-- | includes/deferred/HTMLCacheUpdate.php | 5 | ||||
-rw-r--r-- | includes/deferred/LinksUpdate.php | 33 | ||||
-rw-r--r-- | includes/deferred/SearchUpdate.php | 7 | ||||
-rw-r--r-- | includes/deferred/SiteStatsUpdate.php | 9 | ||||
-rw-r--r-- | includes/deferred/SqlDataUpdate.php | 85 | ||||
-rw-r--r-- | includes/deferred/SquidUpdate.php | 43 | ||||
-rw-r--r-- | includes/deferred/ViewCountUpdate.php | 119 |
8 files changed, 60 insertions, 247 deletions
diff --git a/includes/deferred/DeferredUpdates.php b/includes/deferred/DeferredUpdates.php index b0c1899f..42816ddc 100644 --- a/includes/deferred/DeferredUpdates.php +++ b/includes/deferred/DeferredUpdates.php @@ -82,13 +82,10 @@ class DeferredUpdates { public static function doUpdates( $commit = '' ) { global $wgDeferredUpdateList; - wfProfileIn( __METHOD__ ); - $updates = array_merge( $wgDeferredUpdateList, self::$updates ); // No need to get master connections in case of empty updates array if ( !count( $updates ) ) { - wfProfileOut( __METHOD__ ); return; } @@ -110,7 +107,7 @@ class DeferredUpdates { if ( $doCommit && $dbw->trxLevel() ) { $dbw->commit( __METHOD__, 'flush' ); } - } catch ( MWException $e ) { + } catch ( Exception $e ) { // We don't want exceptions thrown during deferred updates to // be reported to the user since the output is already sent. // Instead we just log them. @@ -122,7 +119,6 @@ class DeferredUpdates { $updates = array_merge( $wgDeferredUpdateList, self::$updates ); } - wfProfileOut( __METHOD__ ); } /** diff --git a/includes/deferred/HTMLCacheUpdate.php b/includes/deferred/HTMLCacheUpdate.php index 54fa5943..79a10e68 100644 --- a/includes/deferred/HTMLCacheUpdate.php +++ b/includes/deferred/HTMLCacheUpdate.php @@ -43,12 +43,11 @@ class HTMLCacheUpdate implements DeferrableUpdate { } public function doUpdate() { - wfProfileIn( __METHOD__ ); - $job = new HTMLCacheUpdateJob( $this->mTitle, array( 'table' => $this->mTable, + 'recursive' => true ) + Job::newRootJobParams( // "overall" refresh links job info "htmlCacheUpdate:{$this->mTable}:{$this->mTitle->getPrefixedText()}" ) @@ -64,7 +63,5 @@ class HTMLCacheUpdate implements DeferrableUpdate { $job->run(); // just do the purge query now } ); } - - wfProfileOut( __METHOD__ ); } } diff --git a/includes/deferred/LinksUpdate.php b/includes/deferred/LinksUpdate.php index 45d26648..e4f00e75 100644 --- a/includes/deferred/LinksUpdate.php +++ b/includes/deferred/LinksUpdate.php @@ -58,12 +58,6 @@ class LinksUpdate extends SqlDataUpdate { /** @var array Map of arbitrary name to value */ public $mProperties; - /** @var DatabaseBase Database connection reference */ - public $mDb; - - /** @var array SELECT options to be used */ - public $mOptions; - /** @var bool Whether to queue jobs for recursive updates */ public $mRecursive; @@ -140,20 +134,19 @@ class LinksUpdate extends SqlDataUpdate { $this->mRecursive = $recursive; - wfRunHooks( 'LinksUpdateConstructed', array( &$this ) ); + Hooks::run( 'LinksUpdateConstructed', array( &$this ) ); } /** * Update link tables with outgoing links from an updated article */ public function doUpdate() { - wfRunHooks( 'LinksUpdate', array( &$this ) ); + Hooks::run( 'LinksUpdate', array( &$this ) ); $this->doIncrementalUpdate(); - wfRunHooks( 'LinksUpdateComplete', array( &$this ) ); + Hooks::run( 'LinksUpdateComplete', array( &$this ) ); } protected function doIncrementalUpdate() { - wfProfileIn( __METHOD__ ); # Page links $existing = $this->getExistingLinks(); @@ -227,7 +220,6 @@ class LinksUpdate extends SqlDataUpdate { $this->queueRecursiveJobs(); } - wfProfileOut( __METHOD__ ); } /** @@ -236,12 +228,24 @@ class LinksUpdate extends SqlDataUpdate { * Which means do LinksUpdate on all pages that include the current page, * using the job queue. */ - function queueRecursiveJobs() { + protected function queueRecursiveJobs() { self::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' ); if ( $this->mTitle->getNamespace() == NS_FILE ) { // Process imagelinks in case the title is or was a redirect self::queueRecursiveJobsForTable( $this->mTitle, 'imagelinks' ); } + + $bc = $this->mTitle->getBacklinkCache(); + // Get jobs for cascade-protected backlinks for a high priority queue. + // If meta-templates change to using a new template, the new template + // should be implicitly protected as soon as possible, if applicable. + // These jobs duplicate a subset of the above ones, but can run sooner. + // Which ever runs first generally no-ops the other one. + $jobs = array(); + foreach ( $bc->getCascadeProtectedLinks() as $title ) { + $jobs[] = new RefreshLinksJob( $title, array( 'prioritize' => true ) ); + } + JobQueueGroup::singleton()->push( $jobs ); } /** @@ -251,7 +255,6 @@ class LinksUpdate extends SqlDataUpdate { * @param string $table Table to use (e.g. 'templatelinks') */ public static function queueRecursiveJobsForTable( Title $title, $table ) { - wfProfileIn( __METHOD__ ); if ( $title->getBacklinkCache()->hasLinks( $table ) ) { $job = new RefreshLinksJob( $title, @@ -262,10 +265,10 @@ class LinksUpdate extends SqlDataUpdate { "refreshlinks:{$table}:{$title->getPrefixedText()}" ) ); + JobQueueGroup::singleton()->push( $job ); JobQueueGroup::singleton()->deduplicateRootJob( $job ); } - wfProfileOut( __METHOD__ ); } /** @@ -339,7 +342,7 @@ class LinksUpdate extends SqlDataUpdate { } if ( count( $insertions ) ) { $this->mDb->insert( $table, $insertions, __METHOD__, 'IGNORE' ); - wfRunHooks( 'LinksUpdateAfterInsert', array( $this, $table, $insertions ) ); + Hooks::run( 'LinksUpdateAfterInsert', array( $this, $table, $insertions ) ); } } diff --git a/includes/deferred/SearchUpdate.php b/includes/deferred/SearchUpdate.php index 5d084afd..ba14f099 100644 --- a/includes/deferred/SearchUpdate.php +++ b/includes/deferred/SearchUpdate.php @@ -78,9 +78,7 @@ class SearchUpdate implements DeferrableUpdate { return; } - wfProfileIn( __METHOD__ ); - - $page = WikiPage::newFromId( $this->id, WikiPage::READ_LATEST ); + $page = WikiPage::newFromID( $this->id, WikiPage::READ_LATEST ); foreach ( SearchEngine::getSearchTypes() as $type ) { $search = SearchEngine::create( $type ); @@ -108,7 +106,6 @@ class SearchUpdate implements DeferrableUpdate { $search->update( $this->id, $normalTitle, $search->normalizeText( $text ) ); } - wfProfileOut( __METHOD__ ); } /** @@ -125,7 +122,6 @@ class SearchUpdate implements DeferrableUpdate { $text = $wgContLang->normalizeForSearch( $text ); $lc = SearchEngine::legalSearchChars() . '&#;'; - wfProfileIn( __METHOD__ . '-regexps' ); $text = preg_replace( "/<\\/?\\s*[A-Za-z][^>]*?>/", ' ', $wgContLang->lc( " " . $text . " " ) ); # Strip HTML markup $text = preg_replace( "/(^|\\n)==\\s*([^\\n]+)\\s*==(\\s)/sD", @@ -172,7 +168,6 @@ class SearchUpdate implements DeferrableUpdate { # Strip wiki '' and ''' $text = preg_replace( "/''[']*/", " ", $text ); - wfProfileOut( __METHOD__ . '-regexps' ); return $text; } diff --git a/includes/deferred/SiteStatsUpdate.php b/includes/deferred/SiteStatsUpdate.php index 7bfafee8..97a17c39 100644 --- a/includes/deferred/SiteStatsUpdate.php +++ b/includes/deferred/SiteStatsUpdate.php @@ -23,9 +23,6 @@ */ class SiteStatsUpdate implements DeferrableUpdate { /** @var int */ - protected $views = 0; - - /** @var int */ protected $edits = 0; /** @var int */ @@ -42,7 +39,6 @@ class SiteStatsUpdate implements DeferrableUpdate { // @todo deprecate this constructor function __construct( $views, $edits, $good, $pages = 0, $users = 0 ) { - $this->views = $views; $this->edits = $edits; $this->articles = $good; $this->pages = $pages; @@ -100,7 +96,6 @@ class SiteStatsUpdate implements DeferrableUpdate { } $pd = $this->getPendingDeltas(); // Piggy-back the async deltas onto those of this stats update.... - $this->views += ( $pd['ss_total_views']['+'] - $pd['ss_total_views']['-'] ); $this->edits += ( $pd['ss_total_edits']['+'] - $pd['ss_total_edits']['-'] ); $this->articles += ( $pd['ss_good_articles']['+'] - $pd['ss_good_articles']['-'] ); $this->pages += ( $pd['ss_total_pages']['+'] - $pd['ss_total_pages']['-'] ); @@ -110,7 +105,6 @@ class SiteStatsUpdate implements DeferrableUpdate { // Build up an SQL query of deltas and apply them... $updates = ''; - $this->appendUpdate( $updates, 'ss_total_views', $this->views ); $this->appendUpdate( $updates, 'ss_total_edits', $this->edits ); $this->appendUpdate( $updates, 'ss_good_articles', $this->articles ); $this->appendUpdate( $updates, 'ss_total_pages', $this->pages ); @@ -160,7 +154,6 @@ class SiteStatsUpdate implements DeferrableUpdate { } protected function doUpdatePendingDeltas() { - $this->adjustPending( 'ss_total_views', $this->views ); $this->adjustPending( 'ss_total_edits', $this->edits ); $this->adjustPending( 'ss_good_articles', $this->articles ); $this->adjustPending( 'ss_total_pages', $this->pages ); @@ -226,7 +219,7 @@ class SiteStatsUpdate implements DeferrableUpdate { global $wgMemc; $pending = array(); - foreach ( array( 'ss_total_views', 'ss_total_edits', + foreach ( array( 'ss_total_edits', 'ss_good_articles', 'ss_total_pages', 'ss_users', 'ss_images' ) as $type ) { // Get pending increments and pending decrements diff --git a/includes/deferred/SqlDataUpdate.php b/includes/deferred/SqlDataUpdate.php index 9c58503f..49164e33 100644 --- a/includes/deferred/SqlDataUpdate.php +++ b/includes/deferred/SqlDataUpdate.php @@ -31,11 +31,11 @@ * the beginTransaction() and commitTransaction() methods. */ abstract class SqlDataUpdate extends DataUpdate { - /** @var DatabaseBase Database connection reference */ + /** @var IDatabase Database connection reference */ protected $mDb; /** @var array SELECT options to be used (array) */ - protected $mOptions; + protected $mOptions = array(); /** @var bool Whether a transaction is open on this object (internal use only!) */ private $mHasTransaction; @@ -51,19 +51,9 @@ abstract class SqlDataUpdate extends DataUpdate { * transaction is already in progress, see beginTransaction() for details. */ public function __construct( $withTransaction = true ) { - global $wgAntiLockFlags; - parent::__construct(); - if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) { - $this->mOptions = array(); - } else { - $this->mOptions = array( 'FOR UPDATE' ); - } - - // @todo Get connection only when it's needed? Make sure that doesn't - // break anything, especially transactions! - $this->mDb = wfGetDB( DB_MASTER ); + $this->mDb = wfGetLB()->getLazyConnectionRef( DB_MASTER ); $this->mWithTransaction = $withTransaction; $this->mHasTransaction = false; @@ -121,39 +111,40 @@ abstract class SqlDataUpdate extends DataUpdate { return; } - /** - * Determine which pages need to be updated - * This is necessary to prevent the job queue from smashing the DB with - * large numbers of concurrent invalidations of the same page - */ - $now = $this->mDb->timestamp(); - $ids = array(); - $res = $this->mDb->select( 'page', array( 'page_id' ), - array( - 'page_namespace' => $namespace, - 'page_title' => $dbkeys, - 'page_touched < ' . $this->mDb->addQuotes( $now ) - ), __METHOD__ - ); - - foreach ( $res as $row ) { - $ids[] = $row->page_id; - } - - if ( $ids === array() ) { - return; - } - - /** - * Do the update - * We still need the page_touched condition, in case the row has changed since - * the non-locking select above. - */ - $this->mDb->update( 'page', array( 'page_touched' => $now ), - array( - 'page_id' => $ids, - 'page_touched < ' . $this->mDb->addQuotes( $now ) - ), __METHOD__ - ); + $dbw = $this->mDb; + $dbw->onTransactionPreCommitOrIdle( function() use ( $dbw, $namespace, $dbkeys ) { + /** + * Determine which pages need to be updated + * This is necessary to prevent the job queue from smashing the DB with + * large numbers of concurrent invalidations of the same page + */ + $now = $dbw->timestamp(); + $ids = $dbw->selectFieldValues( 'page', + 'page_id', + array( + 'page_namespace' => $namespace, + 'page_title' => $dbkeys, + 'page_touched < ' . $dbw->addQuotes( $now ) + ), + __METHOD__ + ); + + if ( $ids === array() ) { + return; + } + + /** + * Do the update + * We still need the page_touched condition, in case the row has changed since + * the non-locking select above. + */ + $dbw->update( 'page', + array( 'page_touched' => $now ), + array( + 'page_id' => $ids, + 'page_touched < ' . $dbw->addQuotes( $now ) + ), __METHOD__ + ); + } ); } } diff --git a/includes/deferred/SquidUpdate.php b/includes/deferred/SquidUpdate.php index 0dcff44a..950a264a 100644 --- a/includes/deferred/SquidUpdate.php +++ b/includes/deferred/SquidUpdate.php @@ -52,41 +52,6 @@ class SquidUpdate { } /** - * Create a SquidUpdate from the given Title object. - * - * The resulting SquidUpdate will purge the given Title's URLs as well as - * the pages that link to it. Capped at $wgMaxSquidPurgeTitles total URLs. - * - * @param Title $title - * @return SquidUpdate - */ - public static function newFromLinksTo( Title $title ) { - global $wgMaxSquidPurgeTitles; - wfProfileIn( __METHOD__ ); - - # Get a list of URLs linking to this page - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( array( 'links', 'page' ), - array( 'page_namespace', 'page_title' ), - array( - 'pl_namespace' => $title->getNamespace(), - 'pl_title' => $title->getDBkey(), - 'pl_from=page_id' ), - __METHOD__ ); - $blurlArr = $title->getSquidURLs(); - if ( $res->numRows() <= $wgMaxSquidPurgeTitles ) { - foreach ( $res as $BL ) { - $tobj = Title::makeTitle( $BL->page_namespace, $BL->page_title ); - $blurlArr[] = $tobj->getInternalURL(); - } - } - - wfProfileOut( __METHOD__ ); - - return new SquidUpdate( $blurlArr ); - } - - /** * Create a SquidUpdate from an array of Title objects, or a TitleArray object * * @param array $titles @@ -145,8 +110,6 @@ class SquidUpdate { self::HTCPPurge( $urlArr ); } - wfProfileIn( __METHOD__ ); - // Remove duplicate URLs $urlArr = array_unique( $urlArr ); // Maximum number of parallel connections per squid @@ -172,7 +135,6 @@ class SquidUpdate { } $pool->run(); - wfProfileOut( __METHOD__ ); } /** @@ -183,7 +145,6 @@ class SquidUpdate { */ public static function HTCPPurge( $urlArr ) { global $wgHTCPRouting, $wgHTCPMulticastTTL; - wfProfileIn( __METHOD__ ); // HTCP CLR operation $htcpOpCLR = 4; @@ -201,7 +162,6 @@ class SquidUpdate { $errstr = socket_strerror( socket_last_error() ); wfDebugLog( 'squid', __METHOD__ . ": Error opening UDP socket: $errstr" ); - wfProfileOut( __METHOD__ ); return; } @@ -223,7 +183,6 @@ class SquidUpdate { foreach ( $urlArr as $url ) { if ( !is_string( $url ) ) { - wfProfileOut( __METHOD__ ); throw new MWException( 'Bad purge URL' ); } $url = self::expand( $url ); @@ -240,7 +199,6 @@ class SquidUpdate { } foreach ( $conf as $subconf ) { if ( !isset( $subconf['host'] ) || !isset( $subconf['port'] ) ) { - wfProfileOut( __METHOD__ ); throw new MWException( "Invalid HTCP rule for URL $url\n" ); } } @@ -272,7 +230,6 @@ class SquidUpdate { $subconf['host'], $subconf['port'] ); } } - wfProfileOut( __METHOD__ ); } /** diff --git a/includes/deferred/ViewCountUpdate.php b/includes/deferred/ViewCountUpdate.php deleted file mode 100644 index 8282295b..00000000 --- a/includes/deferred/ViewCountUpdate.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * Update for the 'page_counter' field - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -/** - * Update for the 'page_counter' field, when $wgDisableCounters is false. - * - * Depending on $wgHitcounterUpdateFreq, this will directly increment the - * 'page_counter' field or use the 'hitcounter' table and then collect the data - * from that table to update the 'page_counter' field in a batch operation. - */ -class ViewCountUpdate implements DeferrableUpdate { - /** @var int Page ID to increment the view count */ - protected $id; - - /** - * Constructor - * - * @param int $id Page ID to increment the view count - */ - public function __construct( $id ) { - $this->id = intval( $id ); - } - - /** - * Run the update - */ - public function doUpdate() { - global $wgHitcounterUpdateFreq; - - $dbw = wfGetDB( DB_MASTER ); - - if ( $wgHitcounterUpdateFreq <= 1 || $dbw->getType() == 'sqlite' ) { - $id = $this->id; - $method = __METHOD__; - $dbw->onTransactionIdle( function () use ( $dbw, $id, $method ) { - try { - $dbw->update( 'page', - array( 'page_counter = page_counter + 1' ), - array( 'page_id' => $id ), - $method - ); - } catch ( DBError $e ) { - MWExceptionHandler::logException( $e ); - } - } ); - return; - } - - # Not important enough to warrant an error page in case of failure - try { - // Since `hitcounter` is non-transactional, the contention is minimal - $dbw->insert( 'hitcounter', array( 'hc_id' => $this->id ), __METHOD__ ); - $checkfreq = intval( $wgHitcounterUpdateFreq / 25 + 1 ); - if ( rand() % $checkfreq == 0 && $dbw->lastErrno() == 0 ) { - $this->collect(); - } - } catch ( DBError $e ) { - MWExceptionHandler::logException( $e ); - } - } - - protected function collect() { - global $wgHitcounterUpdateFreq; - - $dbw = wfGetDB( DB_MASTER ); - - $rown = $dbw->selectField( 'hitcounter', 'COUNT(*)', array(), __METHOD__ ); - if ( $rown < $wgHitcounterUpdateFreq ) { - return; - } - - wfProfileIn( __METHOD__ . '-collect' ); - $old_user_abort = ignore_user_abort( true ); - - $dbType = $dbw->getType(); - $tabletype = $dbType == 'mysql' ? "ENGINE=HEAP " : ''; - $hitcounterTable = $dbw->tableName( 'hitcounter' ); - $acchitsTable = $dbw->tableName( 'acchits' ); - $pageTable = $dbw->tableName( 'page' ); - - $dbw->lockTables( array(), array( 'hitcounter' ), __METHOD__, false ); - $dbw->query( "CREATE TEMPORARY TABLE $acchitsTable $tabletype AS " . - "SELECT hc_id,COUNT(*) AS hc_n FROM $hitcounterTable " . - 'GROUP BY hc_id', __METHOD__ ); - $dbw->delete( 'hitcounter', '*', __METHOD__ ); - $dbw->unlockTables( __METHOD__ ); - - if ( $dbType == 'mysql' ) { - $dbw->query( "UPDATE $pageTable,$acchitsTable SET page_counter=page_counter + hc_n " . - 'WHERE page_id = hc_id', __METHOD__ ); - } else { - $dbw->query( "UPDATE $pageTable SET page_counter=page_counter + hc_n " . - "FROM $acchitsTable WHERE page_id = hc_id", __METHOD__ ); - } - $dbw->query( "DROP TABLE $acchitsTable", __METHOD__ ); - - ignore_user_abort( $old_user_abort ); - wfProfileOut( __METHOD__ . '-collect' ); - } -} |