jenkins-bot has submitted this change and it was merged.
Change subject: Purge caches after edits to the global user page
......................................................................
Purge caches after edits to the global user page
We need to purge squid/varnish on remote wikis whenever
the global user page is edited. We also need to queue cache updates
for whenever the global user page is created/deleted to change red
links into blue links and vice versa.
Ideally we could purge squid/varnish directly from the central wiki,
however the urls are dependent upon language, gender, and other
global state making it tricky to do so.
So instead just queue jobs on each local wiki which call
Title::purgeSquid(). The jobs take an additional parameter
which conrols whether Title::touchLinks() is additionally
called.
Bug: T76410
Change-Id: Ide5ea120213ba770681af286e1ba6e2b3e95ddb8
---
M GlobalUserPage.body.php
M GlobalUserPage.hooks.php
M GlobalUserPage.php
A GlobalUserPageCacheInvalidator.php
A GlobalUserPageLocalJobSubmitJob.php
A LocalGlobalUserPageCacheUpdateJob.php
M extension.json
7 files changed, 189 insertions(+), 1 deletion(-)
Approvals:
Aaron Schulz: Looks good to me, approved
jenkins-bot: Verified
diff --git a/GlobalUserPage.body.php b/GlobalUserPage.body.php
index 06e14b7..85ab775 100644
--- a/GlobalUserPage.body.php
+++ b/GlobalUserPage.body.php
@@ -364,4 +364,21 @@
$data = $this->makeAPIRequest( $params );
return $data !== false ? $data['parse'] : false;
}
+
+ /**
+ * @return array
+ */
+ public static function getEnabledWikis() {
+ static $list = null;
+ if ( $list === null ) {
+ $list = array();
+ if ( wfRunHooks( 'GlobalUserPageWikis', array( &$list )
) ) {
+ // Fallback if no hook override
+ global $wgLocalDatabases;
+ $list = $wgLocalDatabases;
+ }
+ }
+
+ return $list;
+ }
}
diff --git a/GlobalUserPage.hooks.php b/GlobalUserPage.hooks.php
index 3b9618f..9d11e52 100644
--- a/GlobalUserPage.hooks.php
+++ b/GlobalUserPage.hooks.php
@@ -91,4 +91,61 @@
return true;
}
+
+ /**
+ * Whether a page is the global user page on the central wiki
+ *
+ * @param Title $title
+ * @return bool
+ */
+ protected static function isGlobalUserPage( Title $title ) {
+ global $wgGlobalUserPageDBname;
+ return $wgGlobalUserPageDBname === wfWikiID() // On the central
wiki
+ && $title->inNamespace( NS_USER ) // is a user page
+ && $title->getRootTitle()->equals( $title ); // and is
a root page.
+
+ }
+
+ /**
+ * After a LinksUpdate runs for a user page, queue remote squid purges
+ *
+ * @param LinksUpdate $lu
+ * @return bool
+ */
+ public static function onLinksUpdateComplete( LinksUpdate &$lu ) {
+ $title = $lu->getTitle();
+ if ( self::isGlobalUserPage( $title ) ) {
+ $inv = new GlobalUserPageCacheInvalidator(
$title->getText() );
+ $inv->invalidate();
+ }
+
+ return true;
+ }
+
+ /**
+ * Invalidate cache on remote wikis when a new page is created
+ * Also handles the ArticleDeleteComplete hook
+ *
+ * @param WikiPage $page
+ * @return bool
+ */
+ public static function onPageContentInsertComplete( WikiPage $page ) {
+ $title = $page->getTitle();
+ if ( self::isGlobalUserPage( $title ) ) {
+ $inv = new GlobalUserPageCacheInvalidator(
$title->getText(), array( 'links' ) );
+ $inv->invalidate();
+ }
+
+ return true;
+ }
+
+ /**
+ * Invalidate cache on remote wikis when a user page is deleted
+ *
+ * @param WikiPage $page
+ * @return bool
+ */
+ public static function onArticleDeleteComplete( WikiPage $page ) {
+ return self::onPageContentInsertComplete( $page );
+ }
}
diff --git a/GlobalUserPage.php b/GlobalUserPage.php
index ca465af..0ac267f 100644
--- a/GlobalUserPage.php
+++ b/GlobalUserPage.php
@@ -78,6 +78,11 @@
$wgAutoloadClasses['GlobalUserPage'] = __DIR__ . '/GlobalUserPage.body.php';
$wgAutoloadClasses['GlobalUserPageHooks'] = __DIR__ .
'/GlobalUserPage.hooks.php';
+$wgAutoloadClasses['GlobalUserPageLocalJobSubmitJob'] = __DIR__ .
'/GlobalUserPageLocalJobSubmitJob.php';
+$wgAutoloadClasses['LocalGlobalUserPageCacheUpdateJob'] = __DIR__ .
'/LocalGlobalUserPageCacheUpdateJob.php';
+
+$wgJobClasses['GlobalUserPageLocalJobSubmitJob'] =
'GlobalUserPageLocalJobSubmitJob';
+$wgJobClasses['LocalGlobalUserPageCacheUpdateJob'] =
'LocalGlobalUserPageCacheUpdateJob';
// i18n
$wgMessagesDirs['GlobalUserPage'] = __DIR__ . '/i18n';
@@ -88,6 +93,9 @@
$wgHooks['SkinTemplateNavigation::Universal'][] =
'GlobalUserPageHooks::onSkinTemplateNavigationUniversal';
$wgHooks['LinkBegin'][] = 'GlobalUserPageHooks::brokenLink';
$wgHooks['ArticleFromTitle'][] = 'GlobalUserPageHooks::onArticleFromTitle';
+$wgHooks['LinksUpdateComplete'][] =
'GlobalUserPageHooks::onLinksUpdateComplete';
+$wgHooks['PageContentInsertComplete'][] =
'GlobalUserPageHooks::onPageContentInsertComplete';
+$wgHooks['ArticleDeleteComplete'][] =
'GlobalUserPageHooks::onArticleDeleteComplete';
// Register the CSS as a module with ResourceLoader
$wgResourceModules['ext.GlobalUserPage'] = array(
diff --git a/GlobalUserPageCacheInvalidator.php
b/GlobalUserPageCacheInvalidator.php
new file mode 100644
index 0000000..309b856
--- /dev/null
+++ b/GlobalUserPageCacheInvalidator.php
@@ -0,0 +1,38 @@
+<?php
+
+class GlobalUserPageCacheInvalidator {
+ /**
+ * Username of the user who's userpage needs to be invalidated
+ *
+ * @var string
+ */
+ private $username;
+
+ /**
+ * Array of string options
+ *
+ * @var array
+ */
+ private $options;
+
+ public function __construct( $username, array $options = array() ) {
+ $this->username = $username;
+ $this->options = $options;
+ }
+
+ public function invalidate() {
+ global $wgUseSquid;
+ if ( !$wgUseSquid && !$this->options ) {
+ // No squid and no options means nothing to do!
+ return;
+ }
+
+ JobQueueGroup::singleton()->push( new
GlobalUserPageLocalJobSubmitJob(
+ Title::newFromText( 'User:' . $this->username ),
+ array(
+ 'username' => $this->username,
+ 'touch' => in_array( 'links', $this->options ),
+ )
+ ) );
+ }
+}
diff --git a/GlobalUserPageLocalJobSubmitJob.php
b/GlobalUserPageLocalJobSubmitJob.php
new file mode 100644
index 0000000..ad28ce2
--- /dev/null
+++ b/GlobalUserPageLocalJobSubmitJob.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * Job class that submits LocalGlobalUserPageCacheUpdateJob jobs
+ */
+class GlobalUserPageLocalJobSubmitJob extends Job {
+ public function __construct( Title $title, array $params ) {
+ parent::__construct( 'GlobalUserPageLocalJobSubmitJob', $title,
$params );
+ }
+
+ public function run() {
+ $job = new LocalGlobalUserPageCacheUpdateJob(
+ Title::newFromText( 'User:' . $this->params['username']
),
+ $this->params
+ );
+ foreach ( GlobalUserPage::getEnabledWikis() as $wiki ) {
+ JobQueueGroup::singleton( $wiki )->push( $job );
+ }
+ }
+}
diff --git a/LocalGlobalUserPageCacheUpdateJob.php
b/LocalGlobalUserPageCacheUpdateJob.php
new file mode 100644
index 0000000..6025d36
--- /dev/null
+++ b/LocalGlobalUserPageCacheUpdateJob.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * A job that runs on local wikis to purge squid and possibly
+ * queue local HTMLCacheUpdate jobs
+ */
+class LocalGlobalUserPageCacheUpdateJob extends Job {
+ /**
+ * @param Title $title
+ * @param array $params Should have 'username' and 'touch' keys
+ */
+ public function __construct( Title $title, array $params ) {
+ parent::__construct( 'LocalGlobalUserPageCacheUpdateJob',
$title, $params );
+ }
+
+ public function run() {
+ $title = Title::makeTitleSafe( NS_USER,
$this->params['username'] );
+ // We want to purge the cache of the accompanying page so the
tabs change colors
+ if ( $title->isTalkPage() ) {
+ $other = $title->getSubjectPage();
+ } else {
+ $other = $title->getTalkPage();
+ }
+
+ $title->purgeSquid();
+ $other->purgeSquid();
+ HTMLFileCache::clearFileCache( $title );
+ HTMLFileCache::clearFileCache( $other );
+ if ( $this->params['touch'] ) {
+ $title->touchLinks();
+ }
+ }
+}
diff --git a/extension.json b/extension.json
index a44d4a3..fee65d6 100644
--- a/extension.json
+++ b/extension.json
@@ -20,6 +20,15 @@
],
"ArticleFromTitle": [
"GlobalUserPageHooks::onArticleFromTitle"
+ ],
+ "LinksUpdateComplete": [
+ "GlobalUserPageHooks::onLinksUpdateComplete"
+ ],
+ "PageContentInsertComplete": [
+ "GlobalUserPageHooks::onPageContentInsertComplete"
+ ],
+ "ArticleDeleteComplete": [
+ "GlobalUserPageHooks::onArticleDeleteComplete"
]
},
"MessagesDirs": {
@@ -46,7 +55,13 @@
},
"AutoloadClasses": {
"GlobalUserPage": "GlobalUserPage.body.php",
- "GlobalUserPageHooks": "GlobalUserPage.hooks.php"
+ "GlobalUserPageHooks": "GlobalUserPage.hooks.php",
+ "GlobalUserPageLocalJobSubmitJob":
"GlobalUserPageLocalJobSubmitJob.php",
+ "LocalGlobalUserPageCacheUpdateJob":
"LocalGlobalUserPageCacheUpdateJob.php"
+ },
+ "JobClasses": {
+ "GlobalUserPageLocalJobSubmitJob":
"GlobalUserPageLocalJobSubmitJob",
+ "LocalGlobalUserPageCacheUpdateJob":
"LocalGlobalUserPageCacheUpdateJob"
},
"ConfigRegistry": {
"globaluserpage": "GlobalVarConfig::newInstance"
--
To view, visit https://gerrit.wikimedia.org/r/178779
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ide5ea120213ba770681af286e1ba6e2b3e95ddb8
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/GlobalUserPage
Gerrit-Branch: master
Gerrit-Owner: Legoktm <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: BBlack <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits