From b1e96b592b3e4332273cd45886512bd64d4b1483 Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 5 Apr 2012 15:03:22 +0200 Subject: [PATCH] Introducing abstract base classes for LinksUpdate, so we can nicely handle updates to other kinds of secondary data. Change-Id: Ia5ded103651cd10932650ac03b0743812cab2345 --- includes/AutoLoader.php | 2 + includes/LinksUpdate.php | 119 +++++------------------------ includes/SecondaryDBDataUpdate.php | 97 +++++++++++++++++++++++ includes/SecondaryDataUpdate.php | 69 +++++++++++++++++ 4 files changed, 189 insertions(+), 98 deletions(-) create mode 100644 includes/SecondaryDBDataUpdate.php create mode 100644 includes/SecondaryDataUpdate.php diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 46c62c2636..cd6f7a6fab 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -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', diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php index 27d1dfd221..8c5e61d89a 100644 --- a/includes/LinksUpdate.php +++ b/includes/LinksUpdate.php @@ -19,23 +19,18 @@ * * @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 index 0000000000..7ff18fa78e --- /dev/null +++ b/includes/SecondaryDBDataUpdate.php @@ -0,0 +1,97 @@ +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 index 0000000000..69f6cb1a6a --- /dev/null +++ b/includes/SecondaryDataUpdate.php @@ -0,0 +1,69 @@ +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; + } + +} -- 2.20.1