From 35da1bbd7cb8b4414c4fbcf331473f1024bc638d Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Thu, 14 Mar 2019 17:23:26 -0700 Subject: [PATCH] Add small HtmlCacheUpdater service class to normalize purging code The purge() method handles purging of both file cache and CDN, using a PRESEND deferred update. This avoids code duplication and missing file cache purge calls. Also: * Migrate HTMLCacheUpdate callers to just directly using HTMLCacheUpdateJob * Add HtmlFileCacheUpdate class and defer such updates just like with CDN * Simplify HTMLCacheUpdate constructor parameters * Remove BacklinkCache::clear() calls which do nothing since the backlink query does not actually happen until the job runs Change-Id: Ic453b189a40109a73a9426538608eea87a76befa --- RELEASE-NOTES-1.34 | 3 + autoload.php | 2 + includes/MediaWikiServices.php | 9 ++ includes/ServiceWiring.php | 4 + includes/Title.php | 21 +++-- includes/cache/HTMLFileCache.php | 24 +++-- includes/cache/HtmlCacheUpdater.php | 94 +++++++++++++++++++ includes/deferred/CdnCacheUpdate.php | 14 +-- includes/deferred/HTMLCacheUpdate.php | 27 ++---- includes/deferred/HtmlFileCacheUpdate.php | 61 ++++++++++++ includes/deferred/LinksUpdate.php | 9 +- includes/filerepo/file/File.php | 9 +- includes/filerepo/file/LocalFile.php | 35 ++++--- includes/jobqueue/jobs/HTMLCacheUpdateJob.php | 23 ++--- includes/page/PageArchive.php | 8 +- includes/page/WikiFilePage.php | 7 +- includes/page/WikiPage.php | 55 +++++------ includes/revisiondelete/RevDelFileList.php | 5 +- .../revisiondelete/RevDelRevisionList.php | 6 +- 19 files changed, 298 insertions(+), 118 deletions(-) create mode 100644 includes/cache/HtmlCacheUpdater.php create mode 100644 includes/deferred/HtmlFileCacheUpdate.php diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34 index 8ecc469d67..56a886e447 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -92,6 +92,8 @@ For notes on 1.33.x and older releases, see HISTORY. to add fields to Special:Mute. * (T100896) Skin authors can define custom OOUI themes using OOUIThemePaths. See for details. +* The HtmlCacheUpdater service was added to unify the logic of purging CDN cache + and HTML file cache to simplify callers and make them more consistent. === External library changes in 1.34 === @@ -435,6 +437,7 @@ because of Phabricator reports. * SearchEngine::textAlreadyUpdatedForIndex() is deprecated, given the deprecation above this method is no longer needed/called and should not be implemented by SearchEngine implementation. +* Title::purgeSquid is deprecated. Use MediaWikiServices::getHtmlCacheUpdater. === Other changes in 1.34 === * … diff --git a/autoload.php b/autoload.php index 0208a6d783..ed6bb12aa6 100644 --- a/autoload.php +++ b/autoload.php @@ -642,6 +642,8 @@ $wgAutoloadLocalClasses = [ 'Hooks' => __DIR__ . '/includes/Hooks.php', 'Html' => __DIR__ . '/includes/Html.php', 'HtmlArmor' => __DIR__ . '/includes/libs/HtmlArmor.php', + 'HtmlCacheUpdater' => __DIR__ . '/includes/cache/HtmlCacheUpdater.php', + 'HtmlFileCacheUpdate' => __DIR__ . '/includes/deferred/HtmlFileCacheUpdate.php', 'Http' => __DIR__ . '/includes/http/Http.php', 'HttpError' => __DIR__ . '/includes/exception/HttpError.php', 'HttpStatus' => __DIR__ . '/includes/libs/HttpStatus.php', diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php index 7fda45280a..fb30199ffe 100644 --- a/includes/MediaWikiServices.php +++ b/includes/MediaWikiServices.php @@ -68,6 +68,7 @@ use Wikimedia\Services\NoSuchServiceException; use MediaWiki\Interwiki\InterwikiLookup; use MagicWordFactory; use MediaWiki\Storage\PageEditStash; +use HtmlCacheUpdater; /** * Service locator for MediaWiki core services. @@ -595,6 +596,14 @@ class MediaWikiServices extends ServiceContainer { return $this->getService( 'GenderCache' ); } + /** + * @return HtmlCacheUpdater + * @since 1.34 + */ + public function getHtmlCacheUpdater() { + return $this->getService( 'HtmlCacheUpdater' ); + } + /** * @since 1.31 * @return HttpRequestFactory diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 9073de1c0e..d6b4d65433 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -218,6 +218,10 @@ return [ return new GenderCache( $services->getNamespaceInfo() ); }, + 'HtmlCacheUpdater' => function ( MediaWikiServices $services ) : HtmlCacheUpdater { + return new HtmlCacheUpdater(); + }, + 'HttpRequestFactory' => function ( MediaWikiServices $services ) : HttpRequestFactory { return new HttpRequestFactory(); diff --git a/includes/Title.php b/includes/Title.php index 281f75bac1..674767d37b 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -3432,12 +3432,10 @@ class Title implements LinkTarget, IDBAccessObject { /** * Purge all applicable CDN URLs + * @deprecated 1.34 Use HtmlCacheUpdater */ public function purgeSquid() { - DeferredUpdates::addUpdate( - new CdnCacheUpdate( $this->getCdnUrls() ), - DeferredUpdates::PRESEND - ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $this->getCdnUrls() ); } /** @@ -4245,12 +4243,21 @@ class Title implements LinkTarget, IDBAccessObject { * on the number of links. Typically called on create and delete. */ public function touchLinks() { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this, 'pagelinks', 'page-touch' ) ); + $jobs = []; + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $this, + 'pagelinks', + [ 'causeAction' => 'page-touch' ] + ); if ( $this->mNamespace == NS_CATEGORY ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this, 'categorylinks', 'category-touch' ) + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $this, + 'categorylinks', + [ 'causeAction' => 'category-touch' ] ); } + + JobQueueGroup::singleton()->lazyPush( $jobs ); } /** diff --git a/includes/cache/HTMLFileCache.php b/includes/cache/HTMLFileCache.php index a0d61b259e..6d0b87e6e6 100644 --- a/includes/cache/HTMLFileCache.php +++ b/includes/cache/HTMLFileCache.php @@ -219,21 +219,33 @@ class HTMLFileCache extends FileCacheBase { return $text; } + /** + * @param string[] $prefixedDbKeys List of prefixed DB keys for pages to purge + * @since 1.34 + */ + public static function purge( array $prefixedDbKeys ) { + foreach ( $prefixedDbKeys as $prefixedDbKey ) { + foreach ( self::cacheablePageActions() as $type ) { + $fc = new self( $prefixedDbKey, $type ); + $fc->clearCache(); + } + } + } + /** * Clear the file caches for a page for all actions - * @param Title $title + * @param Traversable|Title[]|Title $titles * @return bool Whether $wgUseFileCache is enabled */ - public static function clearFileCache( Title $title ) { + public static function clearFileCache( $titles ) { $config = MediaWikiServices::getInstance()->getMainConfig(); - if ( !$config->get( 'UseFileCache' ) ) { return false; } - foreach ( self::cacheablePageActions() as $type ) { - $fc = new self( $title, $type ); - $fc->clearCache(); + $titleIterator = ( $titles instanceof Title ) ? [ $titles ] : $titles; + foreach ( $titleIterator as $title ) { + self::purge( [ $title->getPrefixedDBkey() ] ); } return true; diff --git a/includes/cache/HtmlCacheUpdater.php b/includes/cache/HtmlCacheUpdater.php new file mode 100644 index 0000000000..b04428c99b --- /dev/null +++ b/includes/cache/HtmlCacheUpdater.php @@ -0,0 +1,94 @@ +getCdnUrls() ); + } + CdnCacheUpdate::purge( $urls ); // purge once (no "rebound" purges) + } else { + DeferredUpdates::addUpdate( + HtmlFileCacheUpdate::newFromTitles( $titles ), + DeferredUpdates::PRESEND + ); + DeferredUpdates::addUpdate( + CdnCacheUpdate::newFromTitles( $titles, $urls ), + DeferredUpdates::PRESEND + ); + } + } +} diff --git a/includes/deferred/CdnCacheUpdate.php b/includes/deferred/CdnCacheUpdate.php index 66ce9a3ddf..a867f2062e 100644 --- a/includes/deferred/CdnCacheUpdate.php +++ b/includes/deferred/CdnCacheUpdate.php @@ -24,12 +24,12 @@ use Wikimedia\Assert\Assert; use MediaWiki\MediaWikiServices; /** - * Handles purging appropriate CDN URLs given a title (or titles) + * Handles purging the appropriate CDN objects given a list of URLs or Title instances * @ingroup Cache */ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { /** @var string[] Collection of URLs to purge */ - protected $urls = []; + private $urls = []; /** * @param string[] $urlArr Collection of URLs to purge @@ -59,12 +59,9 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { $urlArr = array_merge( $urlArr, $title->getCdnUrls() ); } - return new CdnCacheUpdate( $urlArr ); + return new self( $urlArr ); } - /** - * Purges the list of URLs passed to the constructor. - */ public function doUpdate() { global $wgCdnReboundPurgeDelay; @@ -98,10 +95,9 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate { wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) ); // Reliably broadcast the purge to all edge nodes - $relayer = MediaWikiServices::getInstance()->getEventRelayerGroup() - ->getRelayer( 'cdn-url-purges' ); $ts = microtime( true ); - $relayer->notifyMulti( + $relayerGroup = MediaWikiServices::getInstance()->getEventRelayerGroup(); + $relayerGroup->getRelayer( 'cdn-url-purges' )->notifyMulti( 'cdn-url-purges', array_map( function ( $url ) use ( $ts ) { diff --git a/includes/deferred/HTMLCacheUpdate.php b/includes/deferred/HTMLCacheUpdate.php index 29846bfb77..3dd533db7e 100644 --- a/includes/deferred/HTMLCacheUpdate.php +++ b/includes/deferred/HTMLCacheUpdate.php @@ -22,39 +22,32 @@ */ /** - * Class to invalidate the HTML cache of all the pages linking to a given title. + * Class to invalidate the HTML/file cache of all the pages linking to a given title. * * @ingroup Cache + * @deprecated Since 1.34; Enqueue jobs from HTMLCacheUpdateJob::newForBacklinks instead */ class HTMLCacheUpdate extends DataUpdate { /** @var Title */ - public $mTitle; - + private $title; /** @var string */ - public $mTable; + private $table; /** - * @param Title $titleTo + * @param Title $title * @param string $table - * @param string $causeAction Triggering action - * @param string $causeAgent Triggering user */ - function __construct( - Title $titleTo, $table, $causeAction = 'unknown', $causeAgent = 'unknown' - ) { - $this->mTitle = $titleTo; - $this->mTable = $table; - $this->causeAction = $causeAction; - $this->causeAgent = $causeAgent; + public function __construct( Title $title, $table ) { + $this->title = $title; + $this->table = $table; } public function doUpdate() { $job = HTMLCacheUpdateJob::newForBacklinks( - $this->mTitle, - $this->mTable, + $this->title, + $this->table, [ 'causeAction' => $this->getCauseAction(), 'causeAgent' => $this->getCauseAgent() ] ); - JobQueueGroup::singleton()->lazyPush( $job ); } } diff --git a/includes/deferred/HtmlFileCacheUpdate.php b/includes/deferred/HtmlFileCacheUpdate.php new file mode 100644 index 0000000000..7be8b61eab --- /dev/null +++ b/includes/deferred/HtmlFileCacheUpdate.php @@ -0,0 +1,61 @@ +prefixedDbKeys = $prefixedDbKeys; + } + + /** + * Create an update object from an array of Title objects, or a TitleArray object + * + * @param Traversable|Title[] $titles + * @return HtmlFileCacheUpdate + */ + public static function newFromTitles( $titles ) { + $prefixedDbKeys = []; + foreach ( $titles as $title ) { + $prefixedDbKeys[] = $title->getPrefixedDBkey(); + } + + return new self( $prefixedDbKeys ); + } + + public function doUpdate() { + $config = MediaWikiServices::getInstance()->getMainConfig(); + if ( $config->get( 'UseFileCache' ) ) { + HTMLFileCache::purge( $this->prefixedDbKeys ); + } + } +} diff --git a/includes/deferred/LinksUpdate.php b/includes/deferred/LinksUpdate.php index 74e236fd4d..ff293cb9d8 100644 --- a/includes/deferred/LinksUpdate.php +++ b/includes/deferred/LinksUpdate.php @@ -1066,6 +1066,7 @@ class LinksUpdate extends DataUpdate { private function invalidateProperties( $changed ) { global $wgPagePropLinkInvalidations; + $jobs = []; foreach ( $changed as $name => $value ) { if ( isset( $wgPagePropLinkInvalidations[$name] ) ) { $inv = $wgPagePropLinkInvalidations[$name]; @@ -1073,12 +1074,16 @@ class LinksUpdate extends DataUpdate { $inv = [ $inv ]; } foreach ( $inv as $table ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this->mTitle, $table, 'page-props' ) + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $this->mTitle, + $table, + [ 'causeAction' => 'page-props' ] ); } } } + + JobQueueGroup::singleton()->lazyPush( $jobs ); } /** diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index ee7ee6f90d..eca5464942 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -1453,7 +1453,7 @@ abstract class File implements IDBAccessObject { $title = $this->getTitle(); if ( $title ) { $title->invalidateCache(); - $title->purgeSquid(); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $title ); } } @@ -1469,9 +1469,12 @@ abstract class File implements IDBAccessObject { // Purge cache of all pages using this file $title = $this->getTitle(); if ( $title ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $title, 'imagelinks', 'file-purge' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $title, + 'imagelinks', + [ 'causeAction' => 'file-purge' ] ); + JobQueueGroup::singleton()->lazyPush( $job ); } } diff --git a/includes/filerepo/file/LocalFile.php b/includes/filerepo/file/LocalFile.php index 54fc251f4b..989d22283f 100644 --- a/includes/filerepo/file/LocalFile.php +++ b/includes/filerepo/file/LocalFile.php @@ -1047,10 +1047,7 @@ class LocalFile extends File { $this->purgeThumbnails( $options ); // Purge CDN cache for this file - DeferredUpdates::addUpdate( - new CdnCacheUpdate( [ $this->getUrl() ] ), - DeferredUpdates::PRESEND - ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $this->getUrl() ); } /** @@ -1073,7 +1070,7 @@ class LocalFile extends File { foreach ( $files as $file ) { $urls[] = $this->getArchiveThumbUrl( $archiveName, $file ); } - DeferredUpdates::addUpdate( new CdnCacheUpdate( $urls ), DeferredUpdates::PRESEND ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $urls ); } /** @@ -1105,7 +1102,7 @@ class LocalFile extends File { $this->purgeThumbList( $dir, $files ); // Purge the CDN - DeferredUpdates::addUpdate( new CdnCacheUpdate( $urls ), DeferredUpdates::PRESEND ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $urls ); } /** @@ -1725,8 +1722,9 @@ class LocalFile extends File { } } else { # Existing file page: invalidate description page cache - $wikiPage->getTitle()->invalidateCache(); - $wikiPage->getTitle()->purgeSquid(); + $title = $wikiPage->getTitle(); + $title->invalidateCache(); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $title ); # Allow the new file version to be patrolled from the page footer Article::purgePatrolFooterCache( $descId ); } @@ -1774,10 +1772,8 @@ class LocalFile extends File { # Delete old thumbnails $this->purgeThumbnails(); # Remove the old file from the CDN cache - DeferredUpdates::addUpdate( - new CdnCacheUpdate( [ $this->getUrl() ] ), - DeferredUpdates::PRESEND - ); + MediaWikiServices::getInstance() + ->getHtmlCacheUpdater()->purge( $this->getUrl() ); } else { # Update backlink pages pointing to this title if created LinksUpdate::queueRecursiveJobsForTable( @@ -1800,9 +1796,12 @@ class LocalFile extends File { } # Invalidate cache for all pages using this file - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this->getTitle(), 'imagelinks', 'file-upload' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $this->getTitle(), + 'imagelinks', + [ 'causeAction' => 'file-upload', 'causeAgent' => $user->getName() ] ); + JobQueueGroup::singleton()->lazyPush( $job ); return Status::newGood(); } @@ -2004,7 +2003,7 @@ class LocalFile extends File { foreach ( $archiveNames as $archiveName ) { $purgeUrls[] = $this->getArchiveUrl( $archiveName ); } - DeferredUpdates::addUpdate( new CdnCacheUpdate( $purgeUrls ), DeferredUpdates::PRESEND ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $purgeUrls ); return $status; } @@ -2041,10 +2040,8 @@ class LocalFile extends File { $this->purgeDescription(); } - DeferredUpdates::addUpdate( - new CdnCacheUpdate( [ $this->getArchiveUrl( $archiveName ) ] ), - DeferredUpdates::PRESEND - ); + $url = $this->getArchiveUrl( $archiveName ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $url ); return $status; } diff --git a/includes/jobqueue/jobs/HTMLCacheUpdateJob.php b/includes/jobqueue/jobs/HTMLCacheUpdateJob.php index 73fa947790..a2e47343db 100644 --- a/includes/jobqueue/jobs/HTMLCacheUpdateJob.php +++ b/includes/jobqueue/jobs/HTMLCacheUpdateJob.php @@ -25,7 +25,7 @@ use MediaWiki\MediaWikiServices; /** - * Job to purge the cache for all pages that link to or use another page or file + * Job to purge the HTML/file cache for all pages that link to or use another page or file * * This job comes in a few variants: * - a) Recursive jobs to purge caches for backlink pages for a given title. @@ -110,7 +110,7 @@ class HTMLCacheUpdateJob extends Job { * @param array $pages Map of (page ID => (namespace, DB key)) entries */ protected function invalidateTitles( array $pages ) { - global $wgUpdateRowsPerQuery, $wgUseFileCache, $wgPageLanguageUseDB; + global $wgUpdateRowsPerQuery, $wgPageLanguageUseDB; // Get all page IDs in this query into an array $pageIds = array_keys( $pages ); @@ -160,20 +160,11 @@ class HTMLCacheUpdateJob extends Job { __METHOD__ ) ); - // Update CDN; call purge() directly so as to not bother with secondary purges - $urls = []; - foreach ( $titleArray as $title ) { - /** @var Title $title */ - $urls = array_merge( $urls, $title->getCdnUrls() ); - } - CdnCacheUpdate::purge( $urls ); - - // Update file cache - if ( $wgUseFileCache ) { - foreach ( $titleArray as $title ) { - HTMLFileCache::clearFileCache( $title ); - } - } + // Update CDN and file caches (avoiding secondary purge overhead) + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( + $titleArray, + HtmlCacheUpdater::IMMEDIATE_WITHOUT_REBOUND + ); } public function getDeduplicationInfo() { diff --git a/includes/page/PageArchive.php b/includes/page/PageArchive.php index d69a433d9c..19e417abe4 100644 --- a/includes/page/PageArchive.php +++ b/includes/page/PageArchive.php @@ -756,10 +756,14 @@ class PageArchive { Hooks::run( 'ArticleUndelete', [ &$this->title, $created, $comment, $oldPageId, $restoredPages ] ); + if ( $this->title->getNamespace() == NS_FILE ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this->title, 'imagelinks', 'file-restore' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $this->title, + 'imagelinks', + [ 'causeAction' => 'imagelinks', 'causeAgent' => 'file-restore' ] ); + JobQueueGroup::singleton()->lazyPush( $job ); } } diff --git a/includes/page/WikiFilePage.php b/includes/page/WikiFilePage.php index acd506ba79..fd9f7b24d8 100644 --- a/includes/page/WikiFilePage.php +++ b/includes/page/WikiFilePage.php @@ -176,9 +176,12 @@ class WikiFilePage extends WikiPage { if ( $this->mFile->exists() ) { wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" ); - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $this->mTitle, 'imagelinks', 'file-purge' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $this->mTitle, + 'imagelinks', + [ 'causeAction' => 'file-purge' ] ); + JobQueueGroup::singleton()->lazyPush( $job ); } else { wfDebug( 'ImagePage::doPurge no image for ' . $this->mFile->getName() . "; limiting purge to cache only\n" ); diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index 3bc9f7c0f8..33fd4721d4 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -1294,13 +1294,8 @@ class WikiPage implements Page, IDBAccessObject { $this->mTitle->invalidateCache(); - // Clear file cache - HTMLFileCache::clearFileCache( $this->getTitle() ); - // Send purge after above page_touched update was committed - DeferredUpdates::addUpdate( - new CdnCacheUpdate( $this->mTitle->getCdnUrls() ), - DeferredUpdates::PRESEND - ); + // Clear file cache and send purge after above page_touched update was committed + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $this->mTitle ); if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { $messageCache = MessageCache::singleton(); @@ -3384,18 +3379,20 @@ class WikiPage implements Page, IDBAccessObject { // Update existence markers on article/talk tabs... $other = $title->getOtherPage(); - $other->purgeSquid(); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( [ $title, $other ] ); $title->touchLinks(); - $title->purgeSquid(); $title->deleteTitleProtection(); MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title ); // Invalidate caches of articles which include this page - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $title, 'templatelinks', 'page-create' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $title, + 'templatelinks', + [ 'causeAction' => 'page-create' ] ); + JobQueueGroup::singleton()->lazyPush( $job ); if ( $title->getNamespace() == NS_CATEGORY ) { // Load the Category object, which will schedule a job to create @@ -3415,19 +3412,14 @@ class WikiPage implements Page, IDBAccessObject { // TODO: move this into a PageEventEmitter service // Update existence markers on article/talk tabs... - // Clear Backlink cache first so that purge jobs use more up-to-date backlink information - BacklinkCache::get( $title )->clear(); $other = $title->getOtherPage(); - $other->purgeSquid(); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( [ $title, $other ] ); $title->touchLinks(); - $title->purgeSquid(); MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title ); - // File cache - HTMLFileCache::clearFileCache( $title ); InfoAction::invalidateCache( $title ); // Messages @@ -3437,9 +3429,12 @@ class WikiPage implements Page, IDBAccessObject { // Images if ( $title->getNamespace() == NS_FILE ) { - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $title, 'imagelinks', 'page-delete' ) + $job = HTMLCacheUpdateJob::newForBacklinks( + $title, + 'imagelinks', + [ 'causeAction' => 'page-delete' ] ); + JobQueueGroup::singleton()->lazyPush( $job ); } // User talk pages @@ -3472,26 +3467,28 @@ class WikiPage implements Page, IDBAccessObject { ) { // TODO: move this into a PageEventEmitter service - if ( $slotsChanged === null || in_array( SlotRecord::MAIN, $slotsChanged ) ) { + $jobs = []; + if ( $slotsChanged === null || in_array( SlotRecord::MAIN, $slotsChanged ) ) { // Invalidate caches of articles which include this page. // Only for the main slot, because only the main slot is transcluded. // TODO: MCR: not true for TemplateStyles! [SlotHandler] - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $title, 'templatelinks', 'page-edit' ) + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $title, + 'templatelinks', + [ 'causeAction' => 'page-edit' ] ); } - // Invalidate the caches of all pages which redirect here - DeferredUpdates::addUpdate( - new HTMLCacheUpdate( $title, 'redirect', 'page-edit' ) + $jobs[] = HTMLCacheUpdateJob::newForBacklinks( + $title, + 'redirect', + [ 'causeAction' => 'page-edit' ] ); + JobQueueGroup::singleton()->lazyPush( $jobs ); MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title ); - // Purge CDN for this page only - $title->purgeSquid(); - // Clear file cache for this page only - HTMLFileCache::clearFileCache( $title ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $title ); // Purge ?action=info cache $revid = $revision ? $revision->getId() : null; diff --git a/includes/revisiondelete/RevDelFileList.php b/includes/revisiondelete/RevDelFileList.php index ca7bc040d0..d69fa36ca5 100644 --- a/includes/revisiondelete/RevDelFileList.php +++ b/includes/revisiondelete/RevDelFileList.php @@ -122,10 +122,7 @@ class RevDelFileList extends RevDelList { $file->purgeOldThumbnails( $archiveName ); $purgeUrls[] = $file->getArchiveUrl( $archiveName ); } - DeferredUpdates::addUpdate( - new CdnCacheUpdate( $purgeUrls ), - DeferredUpdates::PRESEND - ); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $purgeUrls ); return Status::newGood(); } diff --git a/includes/revisiondelete/RevDelRevisionList.php b/includes/revisiondelete/RevDelRevisionList.php index 0705503e9b..1eaf0cc96c 100644 --- a/includes/revisiondelete/RevDelRevisionList.php +++ b/includes/revisiondelete/RevDelRevisionList.php @@ -19,6 +19,7 @@ * @ingroup RevisionDelete */ +use MediaWiki\MediaWikiServices; use MediaWiki\Storage\RevisionRecord; use Wikimedia\Rdbms\FakeResultWrapper; use Wikimedia\Rdbms\IDatabase; @@ -177,9 +178,10 @@ class RevDelRevisionList extends RevDelList { } public function doPostCommitUpdates( array $visibilityChangeMap ) { - $this->title->purgeSquid(); + MediaWikiServices::getInstance()->getHtmlCacheUpdater()->purge( $this->title ); // Extensions that require referencing previous revisions may need this - Hooks::run( 'ArticleRevisionVisibilitySet', [ $this->title, $this->ids, $visibilityChangeMap ] ); + Hooks::run( 'ArticleRevisionVisibilitySet', + [ $this->title, $this->ids, $visibilityChangeMap ] ); return Status::newGood(); } } -- 2.20.1