Aaron Schulz has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/97659


Change subject: Added support for purging backlinks in the wiki farm
......................................................................

Added support for purging backlinks in the wiki farm

* This adds a $wgGlobalUsageSharedRepoWiki and a $wgGlobalUsagePurgeBacklinks 
variable
* This works by pushing jobs on the repo wiki that push HTMLCacheUpdateJob jobs 
on all
  the client wikis for the imagelinks table

bug 22390

Change-Id: Ib764e9774d208a8b20d4d67db229c24fd21734c8
---
M .gitignore
M GlobalUsage.php
A GlobalUsageCachePurgeJob.php
M GlobalUsageHooks.php
4 files changed, 120 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/GlobalUsage 
refs/changes/59/97659/1

diff --git a/.gitignore b/.gitignore
index 98b092a..963b2ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 *~
 *.kate-swp
 .*.swp
+/nbproject/private/
\ No newline at end of file
diff --git a/GlobalUsage.php b/GlobalUsage.php
index 408ef12..e43743d 100644
--- a/GlobalUsage.php
+++ b/GlobalUsage.php
@@ -48,16 +48,20 @@
 $wgExtensionMessagesFiles['GlobalUsage'] = $dir . 'GlobalUsage.i18n.php';
 $wgExtensionMessagesFiles['GlobalUsageAliases'] = $dir . 
'GlobalUsage.alias.php';
 
-// Special page classes
 $wgAutoloadClasses['GlobalUsage'] = $dir . 'GlobalUsage_body.php';
 $wgAutoloadClasses['GlobalUsageHooks'] = $dir . 'GlobalUsageHooks.php';
 $wgAutoloadClasses['GlobalUsageImagePageHooks'] = $dir . 
'GlobalUsageImagePageHooks.php';
 $wgAutoloadClasses['SpecialGlobalUsage'] = $dir . 'SpecialGlobalUsage.php';
 $wgAutoloadClasses['GlobalUsageQuery'] = $dir . 'GlobalUsageQuery.php';
 $wgAutoloadClasses['ApiQueryGlobalUsage'] = $dir . 'ApiQueryGlobalUsage.php';
+$wgAutoloadClasses['GlobalUsageCachePurgeJob'] = $dir . 
'GlobalUsageCachePurgeJob.php';
+
 $wgSpecialPages['GlobalUsage'] = 'SpecialGlobalUsage';
 $wgSpecialPageGroups['GlobalUsage'] = 'media';
+
 $wgAPIPropModules['globalusage'] = 'ApiQueryGlobalUsage';
+
+$wgJobClasses['globalUsageCachePurge'] = 'GlobalUsageCachePurgeJob';
 
 /* Things that can cause link updates:
  * - Local LinksUpdate
@@ -81,3 +85,11 @@
 // If set to false, the local database contains the globalimagelinks table
 // Else set to something understandable to LBFactory
 $wgGlobalUsageDatabase = false;
+
+// Name of the shared repo that backlinks are shared for
+$wgGlobalUsageSharedRepoWiki = false;
+
+// If set to true, this will purge pages on the wikis that use a file when it 
changes.
+// This works by directly inserting HTMLCacheUpdate jobs into the local wikis.
+// @see $wgGlobalUsagePurgeBacklinks
+$wgGlobalUsagePurgeBacklinks = false;
diff --git a/GlobalUsageCachePurgeJob.php b/GlobalUsageCachePurgeJob.php
new file mode 100644
index 0000000..d92cfdf
--- /dev/null
+++ b/GlobalUsageCachePurgeJob.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Class to insert HTMLCacheUpdate jobs on local wikis to purge all pages that 
use
+ * a given shared file. Note that the global and local image link tables are 
assumed
+ * to be in sync, so the later can be used for the local jobs.
+ */
+class GlobalUsageCachePurgeJob extends Job {
+       function __construct( $title, $params, $id = 0 ) {
+               parent::__construct( 'globalUsageCachePurge', $title, $params, 
$id );
+               $this->removeDuplicates = true; // expensive
+       }
+
+       function run() {
+               global $wgGlobalUsageDatabase;
+
+               $title = $this->getTitle();
+               if ( !$title->inNamespace( NS_FILE ) ) {
+                       return true; // umm, OK
+               }
+
+               $filesForPurge = array( $title->getDbKey() ); // title to purge 
backlinks to
+               // All File pages that redirect this one may have backlinks 
that need purging.
+               // These backlinks are probably broken now (missing files or 
double redirects).
+               foreach ( $title->getBacklinkCache()->getLinks( 'redirect' ) as 
$redirTitle ) {
+                       if ( $redirTitle->getNamespace() == NS_FILE ) {
+                               $filesForPurge[] = $redirTitle->getDbKey();
+                       }
+               }
+               // Remove any duplicates in case titles link to themselves
+               $filesForPurge = array_unique( $filesForPurge );
+
+               // Find all wikis that use any of these files in any of their 
pages...
+               $dbr = wfGetDB( DB_SLAVE, array(), $wgGlobalUsageDatabase );
+               $res = $dbr->select(
+                       'globalimagelinks',
+                       array( 'gil_wiki', 'gil_to' ),
+                       array( 'gil_to' => $filesForPurge ),
+                       __METHOD__,
+                       array( 'DISTINCT' )
+               );
+
+               // Build up a list of HTMLCacheUpdateJob jobs to put on each 
affected wiki to clear
+               // the caches for all pages that link to these file pages. 
These jobs will use the
+               // local imagelinks table, which should have the same links 
that the global one has.
+               $jobsByWiki = array();
+               foreach ( $res as $row ) {
+                       $jobsByWiki[$row->gil_wiki][] = new HTMLCacheUpdateJob(
+                               Title::makeTitle( NS_FILE, $row->gil_to ),
+                               array( 'table' => 'imagelinks' )
+                       );
+               }
+
+               // Batch insert the jobs by wiki to save a few round trips
+               foreach ( $jobsByWiki as $wiki => $jobs ) {
+                       JobQueueGroup::singleton( $wiki )->push( $jobs );
+               }
+
+               return true;
+       }
+}
diff --git a/GlobalUsageHooks.php b/GlobalUsageHooks.php
index c279788..d891bee 100644
--- a/GlobalUsageHooks.php
+++ b/GlobalUsageHooks.php
@@ -62,6 +62,7 @@
        /**
         * Hook to TitleMoveComplete
         * Sets the page title in usage table to the new name.
+        * For shared file moves, purges all pages in the wiki farm that use 
the files.
         * @param $ot Title
         * @param $nt Title
         * @param $user User
@@ -72,6 +73,18 @@
        public static function onTitleMoveComplete( $ot, $nt, $user, $pageid, 
$redirid ) {
                $gu = self::getGlobalUsage();
                $gu->moveTo( $pageid, $nt );
+
+               if ( self::fileUpdatesCreatePurgeJobs() ) {
+                       $jobs = array();
+                       if ( $ot->inNamespace( NS_FILE ) ) {
+                               $jobs[] = new GlobalUsageCachePurgeJob( $ot, 
array() );
+                       }
+                       if ( $nt->inNamespace( NS_FILE ) ) {
+                               $jobs[] = new GlobalUsageCachePurgeJob( $nt, 
array() );
+                       }
+                       JobQueueGroup::singleton()->push( $jobs );
+               }
+
                return true;
        }
 
@@ -94,6 +107,7 @@
        /**
         * Hook to FileDeleteComplete
         * Copies the local link table to the global.
+        * Purges all pages in the wiki farm that use the file if it is a 
shared repo file.
         * @param $file File
         * @param $oldimage
         * @param $article Article
@@ -105,13 +119,20 @@
                if ( !$oldimage ) {
                        $gu = self::getGlobalUsage();
                        $gu->copyLocalImagelinks( $file->getTitle() );
+
+                       if ( self::fileUpdatesCreatePurgeJobs() ) {
+                               $job = new GlobalUsageCachePurgeJob( 
$file->getTitle(), array() );
+                               JobQueueGroup::singleton()->push( $job );
+                       }
                }
+
                return true;
        }
 
        /**
         * Hook to FileUndeleteComplete
         * Deletes the file from the global link table.
+        * Purges all pages in the wiki farm that use the file if it is a 
shared repo file.
         * @param $title Title
         * @param $versions
         * @param $user User
@@ -121,22 +142,47 @@
        public static function onFileUndeleteComplete( $title, $versions, 
$user, $reason ) {
                $gu = self::getGlobalUsage();
                $gu->deleteLinksToFile( $title );
+
+               if ( self::fileUpdatesCreatePurgeJobs() ) {
+                       $job = new GlobalUsageCachePurgeJob( $title, array() );
+                       JobQueueGroup::singleton()->push( $job );
+               }
+
                return true;
        }
 
        /**
         * Hook to UploadComplete
         * Deletes the file from the global link table.
+        * Purges all pages in the wiki farm that use the file if it is a 
shared repo file.
         * @param $upload File
         * @return bool
         */
        public static function onUploadComplete( $upload ) {
                $gu = self::getGlobalUsage();
                $gu->deleteLinksToFile( $upload->getTitle() );
+
+               if ( self::fileUpdatesCreatePurgeJobs() ) {
+                       $job = new GlobalUsageCachePurgeJob( 
$upload->getTitle(), array() );
+                       JobQueueGroup::singleton()->push( $job );
+               }
+
                return true;
        }
 
        /**
+        *
+        * Check if file updates on this wiki should cause backlink page purge 
jobs
+        *
+        * @return bool
+        */
+       private static function fileUpdatesCreatePurgeJobs() {
+               global $wgGlobalUsageSharedRepoWiki, 
$wgGlobalUsagePurgeBacklinks;
+
+               return ( $wgGlobalUsagePurgeBacklinks && wfWikiId() === 
$wgGlobalUsageSharedRepoWiki );
+       }
+
+       /**
         * Initializes a GlobalUsage object for the current wiki.
         *
         * @return GlobalUsage

-- 
To view, visit https://gerrit.wikimedia.org/r/97659
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib764e9774d208a8b20d4d67db229c24fd21734c8
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/GlobalUsage
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to