GWicke has uploaded a new change for review. https://gerrit.wikimedia.org/r/60941
Change subject: WIP: Cache invalidation infrastructure for Parsoid varnishes ...................................................................... WIP: Cache invalidation infrastructure for Parsoid varnishes This patch develops a hook-based cache invalidation infrastructure for the Parsoid varnishes, according to http://www.mediawiki.org/wiki/User:GWicke/Minimal_performance_strategy_for_July_release. It is subclassing HTMLCacheUpdateJob so that the recursive batch splitting logic can be shared. A good amount of edit-related hooks are registered, mostly following the example of the FlaggedRevision extension. It looks like we'll get away without a need for any core modifications. Right now the invalidateTitles method in ParsoidCacheUpdateJob just prints the article ids to invalidate. The actual purge requests need to be implemented. Change-Id: I47331bf638dc93cf444ceeecb89ef9f4c3f40ae3 --- A php/Parsoid.hooks.php A php/Parsoid.php A php/Parsoid.setup.php A php/ParsoidCacheUpdateJob.php 4 files changed, 177 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Parsoid refs/changes/41/60941/1 diff --git a/php/Parsoid.hooks.php b/php/Parsoid.hooks.php new file mode 100644 index 0000000..8b166a5 --- /dev/null +++ b/php/Parsoid.hooks.php @@ -0,0 +1,58 @@ +<?php + +class ParsoidHooks { + /** + * + */ + private static function updateTitle ( $title, $revision ) { + $jobs = array(); + $params = array( + 'table' => 'templatelinks' + ); + $jobs[] = new ParsoidCacheUpdateJob( $title, $params ); + $params = array( + 'table' => 'pagelinks' + ); + $jobs[] = new ParsoidCacheUpdateJob( $title, $params ); + Job::batchInsert( $jobs ); + } + + public static function onArticleEditUpdates ( &$article, &$editInfo, $changed ) { + if ( $changed ) { + $revision = $article->getLatest(); + ParsoidHooks::updateTitle( $article->getTitle(), $revision ); + } + return true; + } + + public static function onArticleDeleteComplete ( &$article, User &$user, $reason, $id ) { + $revision = $article->getLatest(); + ParsoidHooks::updateTitle( $article->getTitle(), $revision ); + return true; + } + + public static function onArticleUndelete ( $title, $create ) { + $revision = $title->getLatestRevID(); + ParsoidHooks::updateTitle( $title, $revision ); + return true; + } + + public static function onArticleRevisionVisibilitySet ( &$title ) { + $revision = $title->getLatestRevID(); + ParsoidHooks::updateTitle( $title, $revision ); + return true; + } + + public static function onTitleMoveComplete ( Title &$title, Title &$newtitle, User &$user, $oldid, $newid ) { + ParsoidHooks::updateTitle( $title, $oldid ); + ParsoidHooks::updateTitle( $newtitle, $newid ); + return true; + } + + public static function onFileUpload ( $file ) { + ParsoidHooks::updateTitle( $title, $oldid ); + ParsoidHooks::updateTitle( $newtitle, $newid ); + return true; + } + +} diff --git a/php/Parsoid.php b/php/Parsoid.php new file mode 100644 index 0000000..c15692f --- /dev/null +++ b/php/Parsoid.php @@ -0,0 +1,30 @@ +<?php +/* + Basic cache invalidation for Parsoid + + + 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 +*/ + +if ( !defined( 'MEDIAWIKI' ) ) { + echo "Parsoid extension\n"; + exit( 1 ); +} + +require( dirname( __FILE__ ) . '/Parsoid.setup.php' ); + +# Load hooks that are always set +ParsoidSetup::setUnconditionalHooks(); diff --git a/php/Parsoid.setup.php b/php/Parsoid.setup.php new file mode 100644 index 0000000..2b2b2cb --- /dev/null +++ b/php/Parsoid.setup.php @@ -0,0 +1,41 @@ +<?php +/** + * Class containing basic setup functions. + * This class depends on config variables in LocalSettings.php. + * Note: avoid Parsoid class calls here for performance (like load.php). + */ +class ParsoidSetup { + /** + * Register backend and API hook handlers. + * This function must NOT depend on any config vars. + * + * @return void + */ + public static function setUnconditionalHooks() { + global $wgHooks, $wgAutoloadClasses, $wgJobClasses; + + $dir = dirname( __FILE__ ); + + $wgAutoloadClasses['ParsoidHooks'] = "$dir/Parsoid.hooks.php"; + $wgAutoloadClasses['ParsoidCacheUpdateJob'] = "$dir/ParsoidCacheUpdateJob.php"; + + # Add the ParsoidCacheUpdateJob to the job classes so it can be de-serialized + $wgJobClasses['ParsoidCacheUpdateJob'] = 'ParsoidCacheUpdateJob'; + + # TODO: implement all these! + + # Article edit/create + $wgHooks['ArticleEditUpdates'][] = 'ParsoidHooks::onArticleEditUpdates'; + # Article delete/restore + $wgHooks['ArticleDeleteComplete'][] = 'ParsoidHooks::onArticleDelete'; + $wgHooks['ArticleUndelete'][] = 'ParsoidHooks::onArticleUndelete'; + # Revision delete/restore + $wgHooks['ArticleRevisionVisibilitySet'][] = 'ParsoidHooks::onRevisionDelete'; + # Article move + $wgHooks['TitleMoveComplete'][] = 'ParsoidHooks::onTitleMoveComplete'; + # File upload + $wgHooks['FileUpload'][] = 'ParsoidHooks::onFileUpload'; + # ######## + } +} + diff --git a/php/ParsoidCacheUpdateJob.php b/php/ParsoidCacheUpdateJob.php new file mode 100644 index 0000000..c121280 --- /dev/null +++ b/php/ParsoidCacheUpdateJob.php @@ -0,0 +1,48 @@ +<?php +/* + HTML cache invalidation for the Parsoid varnish caches +*/ +class ParsoidCacheUpdateJob extends HTMLCacheUpdateJob { + /** + * Construct a job + * @param $title Title: the title linked to + * @param array $params job parameters (table, start and end page_ids) + * @param $id Integer: job id + */ + function __construct( $title, $params, $id = 0 ) { + global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery; + + Job::__construct( 'ParsoidCacheUpdateJob', $title, $params, $id ); + + $this->rowsPerJob = $wgUpdateRowsPerJob; + $this->rowsPerQuery = $wgUpdateRowsPerQuery; + $this->blCache = $title->getBacklinkCache(); + } + + /** + * Invalidate an array (or iterator) of Title objects, right now + * @param $titleArray array + */ + protected function invalidateTitles( $titleArray ) { + global $wgUseFileCache, $wgUseSquid; + + $dbw = wfGetDB( DB_MASTER ); + $timestamp = $dbw->timestamp(); + + # Get all IDs in this query into an array + $ids = array(); + foreach ( $titleArray as $title ) { + $ids[] = $title->getArticleID(); + } + + if ( !$ids ) { + return; + } + + wfDebug('ParsoidCacheUpdateJob::invalidateTitles: ' . serialize($ids) . "\n" ); + + # TODO: implement actual update based on titles and revision ids. See + # http://www.mediawiki.org/wiki/Parsoid/Minimal_performance_strategy_for_July_release#Cache_invalidation_hooks + } + +} -- To view, visit https://gerrit.wikimedia.org/r/60941 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I47331bf638dc93cf444ceeecb89ef9f4c3f40ae3 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Parsoid Gerrit-Branch: master Gerrit-Owner: GWicke <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
