Introducing abstract base classes for LinksUpdate, so we can nicely handle updates...
authordaniel <daniel.kinzler@wikimedia.de>
Thu, 5 Apr 2012 13:03:22 +0000 (15:03 +0200)
committerdaniel <daniel.kinzler@wikimedia.de>
Thu, 5 Apr 2012 14:55:02 +0000 (16:55 +0200)
Change-Id: Ia5ded103651cd10932650ac03b0743812cab2345

includes/AutoLoader.php
includes/LinksUpdate.php
includes/SecondaryDBDataUpdate.php [new file with mode: 0644]
includes/SecondaryDataUpdate.php [new file with mode: 0644]

index 46c62c2..cd6f7a6 100644 (file)
@@ -189,6 +189,8 @@ $wgAutoloadLocalClasses = array(
        'RevisionList' => 'includes/RevisionList.php',
        'RSSFeed' => 'includes/Feed.php',
        'Sanitizer' => 'includes/Sanitizer.php',
+    'SecondaryDataUpdate' => 'includes/SecondaryDataUpdate.php',
+    'SecondaryDBDataUpdate' => 'includes/SecondaryDBDataUpdate.php',
        'SiteConfiguration' => 'includes/SiteConfiguration.php',
        'SiteStats' => 'includes/SiteStats.php',
        'SiteStatsInit' => 'includes/SiteStats.php',
index 27d1dfd..8c5e61d 100644 (file)
  *
  * @todo document (e.g. one-sentence top-level class description).
  */
-class LinksUpdate {
+class LinksUpdate extends SecondaryDBDataUpdate {
 
        /**@{{
         * @private
         */
-       var $mId,            //!< Page ID of the article linked from
-               $mTitle,         //!< Title object of the article linked from
-               $mParserOutput,  //!< Parser output
-               $mLinks,         //!< Map of title strings to IDs for the links in the document
+       var $mLinks,         //!< Map of title strings to IDs for the links in the document
                $mImages,        //!< DB keys of the images used, in the array key only
                $mTemplates,     //!< Map of title strings to IDs for the template references, including broken ones
                $mExternals,     //!< URLs of external links, array key only
                $mCategories,    //!< Map of category names to sort keys
                $mInterlangs,    //!< Map of language codes to titles
                $mProperties,    //!< Map of arbitrary name to value
-               $mDb,            //!< Database connection reference
-               $mOptions,       //!< SELECT options to be used (array)
                $mRecursive;     //!< Whether to queue jobs for recursive updates
        /**@}}*/
 
@@ -47,23 +42,13 @@ class LinksUpdate {
         * @param $recursive Boolean: queue jobs for recursive updates?
         */
        function __construct( $title, $parserOutput, $recursive = true ) {
-               global $wgAntiLockFlags;
+        if ( !is_object( $title ) ) {
+            throw new MWException( "The calling convention to LinksUpdate::LinksUpdate() has changed. " .
+                "Please see Article::editUpdates() for an invocation example.\n" );
+        }
 
-               if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) {
-                       $this->mOptions = array();
-               } else {
-                       $this->mOptions = array( 'FOR UPDATE' );
-               }
-               $this->mDb = wfGetDB( DB_MASTER );
+        parent::__construct( $title, $parserOutput );
 
-               if ( !is_object( $title ) ) {
-                       throw new MWException( "The calling convention to LinksUpdate::LinksUpdate() has changed. " .
-                               "Please see Article::editUpdates() for an invocation example.\n" );
-               }
-               $this->mTitle = $title;
-               $this->mId = $title->getArticleID();
-
-               $this->mParserOutput = $parserOutput;
                $this->mLinks = $parserOutput->getLinks();
                $this->mImages = $parserOutput->getImages();
                $this->mTemplates = $parserOutput->getTemplates();
@@ -253,51 +238,6 @@ class LinksUpdate {
                wfProfileOut( __METHOD__ );
        }
 
-       /**
-        * Invalidate the cache of a list of pages from a single namespace
-        *
-        * @param $namespace Integer
-        * @param $dbkeys Array
-        */
-       function invalidatePages( $namespace, $dbkeys ) {
-               if ( !count( $dbkeys ) ) {
-                       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 IN (' . $this->mDb->makeList( $dbkeys ) . ')',
-                               'page_touched < ' . $this->mDb->addQuotes( $now )
-                       ), __METHOD__
-               );
-               foreach ( $res as $row ) {
-                       $ids[] = $row->page_id;
-               }
-               if ( !count( $ids ) ) {
-                       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 IN (' . $this->mDb->makeList( $ids ) . ')',
-                               'page_touched < ' . $this->mDb->addQuotes( $now )
-                       ), __METHOD__
-               );
-       }
-
        /**
         * @param $cats
         */
@@ -324,20 +264,20 @@ class LinksUpdate {
                $this->invalidatePages( NS_FILE, array_keys( $images ) );
        }
 
-       /**
-        * @param $table
-        * @param $insertions
-        * @param $fromField
-        */
-       private function dumbTableUpdate( $table, $insertions, $fromField ) {
-               $this->mDb->delete( $table, array( $fromField => $this->mId ), __METHOD__ );
-               if ( count( $insertions ) ) {
-                       # The link array was constructed without FOR UPDATE, so there may
-                       # be collisions.  This may cause minor link table inconsistencies,
-                       # which is better than crippling the site with lock contention.
-                       $this->mDb->insert( $table, $insertions, __METHOD__, array( 'IGNORE' ) );
-               }
-       }
+    /**
+     * @param $table
+     * @param $insertions
+     * @param $fromField
+     */
+    private function dumbTableUpdate( $table, $insertions, $fromField ) {
+        $this->mDb->delete( $table, array( $fromField => $this->mId ), __METHOD__ );
+        if ( count( $insertions ) ) {
+            # The link array was constructed without FOR UPDATE, so there may
+            # be collisions.  This may cause minor link table inconsistencies,
+            # which is better than crippling the site with lock contention.
+            $this->mDb->insert( $table, $insertions, __METHOD__, array( 'IGNORE' ) );
+        }
+    }
 
        /**
         * Update a table by doing a delete query then an insert query
@@ -803,23 +743,6 @@ class LinksUpdate {
                return $arr;
        }
 
-       /**
-        * Return the title object of the page being updated
-        * @return Title
-        */
-       public function getTitle() {
-               return $this->mTitle;
-       }
-
-       /**
-        * Returns parser output
-        * @since 1.19
-        * @return ParserOutput
-        */
-       public function getParserOutput() {
-               return $this->mParserOutput;
-       }
-
        /**
         * Return the list of images used as generated by the parser
         * @return array
diff --git a/includes/SecondaryDBDataUpdate.php b/includes/SecondaryDBDataUpdate.php
new file mode 100644 (file)
index 0000000..7ff18fa
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+/**
+ * See docs/deferred.txt
+ *
+ * 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
+ *
+ * Abstract base class for update jobs that put some secondary data extracted
+ * from article content into the database.
+ */
+abstract class SecondaryDBDataUpdate extends SecondaryDataUpdate {
+
+       /**@{{
+        * @private
+        */
+       var $mDb,            //!< Database connection reference
+               $mOptions;       //!< SELECT options to be used (array)
+       /**@}}*/
+
+       /**
+        * Constructor
+        *
+        * @param $title Title of the page we're updating
+        * @param $parserOutput ParserOutput: output from a full parse of this page
+        * @param $recursive Boolean: queue jobs for recursive updates?
+        */
+    public function __construct( Title $title, ParserOutput $parserOutput ) {
+               global $wgAntiLockFlags;
+
+        parent::__construct( $title, $parserOutput );
+
+               if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) {
+                       $this->mOptions = array();
+               } else {
+                       $this->mOptions = array( 'FOR UPDATE' );
+               }
+               $this->mDb = wfGetDB( DB_MASTER );
+       }
+
+       /**
+        * Invalidate the cache of a list of pages from a single namespace
+        *
+        * @param $namespace Integer
+        * @param $dbkeys Array
+        */
+       public function invalidatePages( $namespace, $dbkeys ) {
+               if ( !count( $dbkeys ) ) {
+                       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 IN (' . $this->mDb->makeList( $dbkeys ) . ')',
+                               'page_touched < ' . $this->mDb->addQuotes( $now )
+                       ), __METHOD__
+               );
+               foreach ( $res as $row ) {
+                       $ids[] = $row->page_id;
+               }
+               if ( !count( $ids ) ) {
+                       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 IN (' . $this->mDb->makeList( $ids ) . ')',
+                               'page_touched < ' . $this->mDb->addQuotes( $now )
+                       ), __METHOD__
+               );
+       }
+
+}
diff --git a/includes/SecondaryDataUpdate.php b/includes/SecondaryDataUpdate.php
new file mode 100644 (file)
index 0000000..69f6cb1
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+/**
+ * See docs/deferred.txt
+ *
+ * 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
+ *
+ * Abstract base class for update jobs that do something with some secondary
+ * data extracted from article.
+ */
+abstract class SecondaryDataUpdate {
+
+       /**@{{
+        * @private
+        */
+       var $mId,            //!< Page ID of the article linked from
+               $mTitle,         //!< Title object of the article linked from
+               $mParserOutput;     //!< Whether to queue jobs for recursive updates
+       /**@}}*/
+
+       /**
+        * Constructor
+        *
+        * @param $title Title of the page we're updating
+        * @param $parserOutput ParserOutput: output from a full parse of this page
+        * @param $recursive Boolean: queue jobs for recursive updates?
+        */
+    public function __construct( Title $title, ParserOutput $parserOutput) {
+               $this->mTitle = $title;
+               $this->mId = $title->getArticleID();
+
+               $this->mParserOutput = $parserOutput;
+       }
+
+       /**
+        * Update link tables with outgoing links from an updated article
+        */
+       public abstract function doUpdate();
+
+       /**
+        * Return the title object of the page being updated
+        * @return Title
+        */
+       public function getTitle() {
+               return $this->mTitle;
+       }
+
+       /**
+        * Returns parser output
+        * @since 1.19
+        * @return ParserOutput
+        */
+       public function getParserOutput() {
+               return $this->mParserOutput;
+       }
+
+}