From 632896e3410652fb61d4dd57a82d5f7ca42854d7 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Thu, 11 Dec 2008 14:29:16 +0000 Subject: [PATCH] Pull up and tweak filecache check to make it much faster and able to for request to avoid a db hit if counters are off and job rate = 0 --- includes/Article.php | 48 ++++++++++------------------------ includes/HTMLFileCache.php | 53 +++++++++++++++++++++++++++++--------- includes/Wiki.php | 21 ++++++++++++++- 3 files changed, 75 insertions(+), 47 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 15ca8c533d..b2fa9b4daa 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -687,7 +687,7 @@ class Article { $parserCache = ParserCache::singleton(); $wgOut->setETag( $parserCache->getETag($this,$wgUser) ); } - if( $wgOut->checkLastModified( $this->getTouched() ) ){ + if( $wgOut->checkLastModified( $this->getTouched() ) ) { wfProfileOut( __METHOD__ ); return; } else if( $this->tryFileCache() ) { @@ -2704,16 +2704,13 @@ class Article { /** * Do standard deferred updates after page view */ - protected function viewUpdates() { - global $wgDeferredUpdateList, $wgUser; - if( 0 != $this->getID() ) { - # Don't update page view counters on views from bot users (bug 14044) - global $wgDisableCounters; - if( !$wgDisableCounters && !$wgUser->isAllowed( 'bot' ) ) { - Article::incViewCount( $this->getID() ); - $u = new SiteStatsUpdate( 1, 0, 0 ); - array_push( $wgDeferredUpdateList, $u ); - } + public function viewUpdates() { + global $wgDeferredUpdateList, $wgDisableCounters, $wgUser; + # Don't update page view counters on views from bot users (bug 14044) + if( !$wgDisableCounters && !$wgUser->isAllowed('bot') && $this->getID() ) { + Article::incViewCount( $this->getID() ); + $u = new SiteStatsUpdate( 1, 0, 0 ); + array_push( $wgDeferredUpdateList, $u ); } # Update newtalk / watchlist notification status $wgUser->clearNotification( $this->mTitle ); @@ -2977,31 +2974,14 @@ class Article { * @return bool */ public function isFileCacheable() { - global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest, $wgLang, $wgContLang; - // Get all query values - $queryVals = $wgRequest->getValues(); - foreach( $queryVals as $query => $val ) { - // Normal page view in query form can have action=view - if( $query !== 'title' && $query !== 'curid' && !($query == 'action' && $val == 'view') ) { - return false; + $cacheable = false; + if( HTMLFileCache::useFileCache() ) { + $cacheable = $this->getID() && !$this->mRedirectedFrom; + // Extension may have reason to disable file caching on some pages. + if( $cacheable ) { + $cacheable = wfRunHooks( 'IsFileCacheable', array( &$this ) ); } } - // Check for non-standard user language; this covers uselang, - // and extensions for auto-detecting user language. - $ulang = $wgLang->getCode(); - $clang = $wgContLang->getCode(); - - $cacheable = $wgUseFileCache - && !$wgShowIPinHeader - && $this->getID() > 0 - && $wgUser->isAnon() - && !$wgUser->getNewtalk() - && !$this->mRedirectedFrom - && $ulang === $clang; - // Extension may have reason to disable file caching on some pages. - if( $cacheable ) { - $cacheable = wfRunHooks( 'IsFileCacheable', array( &$this ) ); - } return $cacheable; } diff --git a/includes/HTMLFileCache.php b/includes/HTMLFileCache.php index 1ff8e1d6a3..299235aeb8 100644 --- a/includes/HTMLFileCache.php +++ b/includes/HTMLFileCache.php @@ -22,12 +22,12 @@ class HTMLFileCache { var $mTitle, $mFileCache; - function HTMLFileCache( &$title ) { + public function __construct( &$title ) { $this->mTitle = $title; $this->mFileCache = $this->fileCacheName(); } - function fileCacheName() { + public function fileCacheName() { global $wgFileCacheDirectory; if( !$this->mFileCache ) { $key = $this->mTitle->getPrefixedDbkey(); @@ -46,37 +46,66 @@ class HTMLFileCache { return $this->mFileCache; } - function isFileCached() { + public function isFileCached() { return file_exists( $this->fileCacheName() ); } - function fileCacheTime() { + public function fileCacheTime() { return wfTimestamp( TS_MW, filemtime( $this->fileCacheName() ) ); } + + /** + * Check if pages can be cached for this request/user + * @return bool + */ + public static function useFileCache() { + global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest, $wgLang, $wgContLang; + if( !$wgUseFileCache ) + return false; + // Get all query values + $queryVals = $wgRequest->getValues(); + foreach( $queryVals as $query => $val ) { + // Normal page view in query form can have action=view + if( $query !== 'title' && $query !== 'curid' && !($query == 'action' && $val == 'view') ) { + return false; + } + } + // Check for non-standard user language; this covers uselang, + // and extensions for auto-detecting user language. + $ulang = $wgLang->getCode(); + $clang = $wgContLang->getCode(); + + return !$wgShowIPinHeader && !$wgUser->getId() && !$wgUser->getNewtalk() && $ulang == $clang; + } - function isFileCacheGood( $timestamp ) { + /* + * Check if up to date cache file exists + * @param $timestamp string + */ + public function isFileCacheGood( $timestamp = '' ) { global $wgCacheEpoch; if( !$this->isFileCached() ) return false; + if( !$timestamp ) return true; // should be invalidated on change $cachetime = $this->fileCacheTime(); $good = $timestamp <= $cachetime && $wgCacheEpoch <= $cachetime; - wfDebug(" isFileCacheGood() - cachetime $cachetime, touched {$timestamp} epoch {$wgCacheEpoch}, good $good\n"); + wfDebug(" isFileCacheGood() - cachetime $cachetime, touched '{$timestamp}' epoch {$wgCacheEpoch}, good $good\n"); return $good; } - function useGzip() { + public function useGzip() { global $wgUseGzip; return $wgUseGzip; } /* In handy string packages */ - function fetchRawText() { + public function fetchRawText() { return file_get_contents( $this->fileCacheName() ); } - function fetchPageText() { + public function fetchPageText() { if( $this->useGzip() ) { /* Why is there no gzfile_get_contents() or gzdecode()? */ return implode( '', gzfile( $this->fileCacheName() ) ); @@ -86,7 +115,7 @@ class HTMLFileCache { } /* Working directory to/from output */ - function loadFromFileCache() { + public function loadFromFileCache() { global $wgOut, $wgMimeType, $wgOutputEncoding, $wgContLanguageCode; wfDebug(" loadFromFileCache()\n"); @@ -108,7 +137,7 @@ class HTMLFileCache { readfile( $filename ); } - function checkCacheDirs() { + protected function checkCacheDirs() { $filename = $this->fileCacheName(); $mydir2 = substr($filename,0,strrpos($filename,'/')); # subdirectory level 2 $mydir1 = substr($mydir2,0,strrpos($mydir2,'/')); # subdirectory level 1 @@ -117,7 +146,7 @@ class HTMLFileCache { wfMkdirParents( $mydir2 ); } - function saveToFileCache( $origtext ) { + public function saveToFileCache( $origtext ) { global $wgUseFileCache; if( !$wgUseFileCache ) { return $origtext; // return to output diff --git a/includes/Wiki.php b/includes/Wiki.php index 3358b4d263..8484954529 100644 --- a/includes/Wiki.php +++ b/includes/Wiki.php @@ -222,6 +222,25 @@ class MediaWiki { /* actions that need to be made when we have a special pages */ SpecialPage::executePath( $title ); } else { + /* Try low-level file cache hit */ + if( $title->getNamespace() != NS_MEDIAWIKI && HTMLFileCache::useFileCache() ) { + $cache = new HTMLFileCache( $title ); + if( $cache->isFileCacheGood( /* Assume up to date */ ) ) { + global $wgOut; + /* Check incoming headers to see if client has this cached */ + if( !$wgOut->checkLastModified( $cache->fileCacheTime() ) ) { + wfDebug( "MediaWiki::initializeSpecialCases(): about to load file cache\n" ); + $cache->loadFromFileCache(); + # Tell $wgOut that output is taken care of + $wgOut->disable(); + # Do any stats increment/watchlist stuff + $article = self::articleFromTitle( $title ); + $article->viewUpdates(); + } + wfProfileOut( __METHOD__ ); + return true; + } + } /* No match to special cases */ wfProfileOut( __METHOD__ ); return false; @@ -325,7 +344,7 @@ class MediaWiki { * @param $deferredUpdates array of updates to do * @param $output OutputPage */ - function finalCleanup ( &$deferredUpdates, &$output ) { + function finalCleanup( &$deferredUpdates, &$output ) { wfProfileIn( __METHOD__ ); # Now commit any transactions, so that unreported errors after output() don't roll back the whole thing $factory = wfGetLBFactory(); -- 2.20.1