summaryrefslogtreecommitdiff
path: root/includes/deferred
diff options
context:
space:
mode:
Diffstat (limited to 'includes/deferred')
-rw-r--r--includes/deferred/DeferredUpdates.php6
-rw-r--r--includes/deferred/HTMLCacheUpdate.php5
-rw-r--r--includes/deferred/LinksUpdate.php33
-rw-r--r--includes/deferred/SearchUpdate.php7
-rw-r--r--includes/deferred/SiteStatsUpdate.php9
-rw-r--r--includes/deferred/SqlDataUpdate.php85
-rw-r--r--includes/deferred/SquidUpdate.php43
-rw-r--r--includes/deferred/ViewCountUpdate.php119
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' );
- }
-}