Fix $wgFileCache DB outage fallback
Change-Id: I5c41b4669ca29d119de5c08a2c61dbadae7cf55c
This commit is contained in:
parent
ef50d30b7b
commit
3ad9e41be9
3 changed files with 56 additions and 21 deletions
|
|
@ -528,6 +528,24 @@ class MediaWiki {
|
||||||
$e->report(); // display the GUI error
|
$e->report(); // display the GUI error
|
||||||
}
|
}
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
|
$context = $this->context;
|
||||||
|
if (
|
||||||
|
$e instanceof DBConnectionError &&
|
||||||
|
$context->hasTitle() &&
|
||||||
|
$context->getTitle()->canExist() &&
|
||||||
|
$context->getRequest()->getVal( 'action', 'view' ) === 'view' &&
|
||||||
|
HTMLFileCache::useFileCache( $this->context, HTMLFileCache::MODE_OUTAGE )
|
||||||
|
) {
|
||||||
|
// Try to use any (even stale) file during outages...
|
||||||
|
$cache = new HTMLFileCache( $context->getTitle(), 'view' );
|
||||||
|
if ( $cache->isCached() ) {
|
||||||
|
$cache->loadFromFileCache( $context, HTMLFileCache::MODE_OUTAGE );
|
||||||
|
print MWExceptionRenderer::getHTML( $e );
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
MWExceptionHandler::handleException( $e );
|
MWExceptionHandler::handleException( $e );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -819,8 +837,7 @@ class MediaWiki {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->config->get( 'UseFileCache' ) && $title->getNamespace() >= 0 ) {
|
if ( $title->canExist() && HTMLFileCache::useFileCache( $this->context ) ) {
|
||||||
if ( HTMLFileCache::useFileCache( $this->context ) ) {
|
|
||||||
// Try low-level file cache hit
|
// Try low-level file cache hit
|
||||||
$cache = new HTMLFileCache( $title, $action );
|
$cache = new HTMLFileCache( $title, $action );
|
||||||
if ( $cache->isCacheGood( /* Assume up to date */ ) ) {
|
if ( $cache->isCacheGood( /* Assume up to date */ ) ) {
|
||||||
|
|
@ -829,8 +846,8 @@ class MediaWiki {
|
||||||
if ( !$output->checkLastModified( $timestamp ) ) {
|
if ( !$output->checkLastModified( $timestamp ) ) {
|
||||||
$cache->loadFromFileCache( $this->context );
|
$cache->loadFromFileCache( $this->context );
|
||||||
}
|
}
|
||||||
// Do any stats increment/watchlist stuff
|
// Do any stats increment/watchlist stuff, assuming user is viewing the
|
||||||
// Assume we're viewing the latest revision (this should always be the case with file cache)
|
// latest revision (which should always be the case for file cache)
|
||||||
$this->context->getWikiPage()->doViewUpdates( $this->context->getUser() );
|
$this->context->getWikiPage()->doViewUpdates( $this->context->getUser() );
|
||||||
// Tell OutputPage that output is taken care of
|
// Tell OutputPage that output is taken care of
|
||||||
$output->disable();
|
$output->disable();
|
||||||
|
|
@ -838,7 +855,6 @@ class MediaWiki {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Actually do the work of the request and build up any output
|
// Actually do the work of the request and build up any output
|
||||||
$this->performRequest();
|
$this->performRequest();
|
||||||
|
|
|
||||||
25
includes/cache/HTMLFileCache.php
vendored
25
includes/cache/HTMLFileCache.php
vendored
|
|
@ -29,6 +29,9 @@
|
||||||
* @ingroup Cache
|
* @ingroup Cache
|
||||||
*/
|
*/
|
||||||
class HTMLFileCache extends FileCacheBase {
|
class HTMLFileCache extends FileCacheBase {
|
||||||
|
const MODE_NORMAL = 0; // normal cache mode
|
||||||
|
const MODE_OUTAGE = 1; // fallback cache for DB outages
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an HTMLFileCache object from a Title and an action
|
* Construct an HTMLFileCache object from a Title and an action
|
||||||
*
|
*
|
||||||
|
|
@ -93,10 +96,12 @@ class HTMLFileCache extends FileCacheBase {
|
||||||
/**
|
/**
|
||||||
* Check if pages can be cached for this request/user
|
* Check if pages can be cached for this request/user
|
||||||
* @param IContextSource $context
|
* @param IContextSource $context
|
||||||
|
* @param integer $mode One of the HTMLFileCache::MODE_* constants
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function useFileCache( IContextSource $context ) {
|
public static function useFileCache( IContextSource $context, $mode = self::MODE_NORMAL ) {
|
||||||
global $wgUseFileCache, $wgDebugToolbar, $wgContLang;
|
global $wgUseFileCache, $wgDebugToolbar, $wgContLang;
|
||||||
|
|
||||||
if ( !$wgUseFileCache ) {
|
if ( !$wgUseFileCache ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -121,15 +126,23 @@ class HTMLFileCache extends FileCacheBase {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $context->getUser();
|
$user = $context->getUser();
|
||||||
// Check for non-standard user language; this covers uselang,
|
// Check for non-standard user language; this covers uselang,
|
||||||
// and extensions for auto-detecting user language.
|
// and extensions for auto-detecting user language.
|
||||||
$ulang = $context->getLanguage();
|
$ulang = $context->getLanguage();
|
||||||
|
|
||||||
// Check that there are no other sources of variation
|
// Check that there are no other sources of variation
|
||||||
if ( $user->getId() || $user->getNewtalk() || !$ulang->equals( $wgContLang ) ) {
|
if ( $user->getId() || !$ulang->equals( $wgContLang ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( $mode === self::MODE_NORMAL ) {
|
||||||
|
if ( $user->getNewtalk() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Allow extensions to disable caching
|
// Allow extensions to disable caching
|
||||||
return Hooks::run( 'HTMLFileCache::useFileCache', [ $context ] );
|
return Hooks::run( 'HTMLFileCache::useFileCache', [ $context ] );
|
||||||
}
|
}
|
||||||
|
|
@ -137,14 +150,20 @@ class HTMLFileCache extends FileCacheBase {
|
||||||
/**
|
/**
|
||||||
* Read from cache to context output
|
* Read from cache to context output
|
||||||
* @param IContextSource $context
|
* @param IContextSource $context
|
||||||
|
* @param integer $mode One of the HTMLFileCache::MODE_* constants
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function loadFromFileCache( IContextSource $context ) {
|
public function loadFromFileCache( IContextSource $context, $mode = self::MODE_NORMAL ) {
|
||||||
global $wgMimeType, $wgLanguageCode;
|
global $wgMimeType, $wgLanguageCode;
|
||||||
|
|
||||||
wfDebug( __METHOD__ . "()\n" );
|
wfDebug( __METHOD__ . "()\n" );
|
||||||
$filename = $this->cachePath();
|
$filename = $this->cachePath();
|
||||||
|
|
||||||
|
if ( $mode === self::MODE_OUTAGE ) {
|
||||||
|
// Avoid DB errors for queries in sendCacheControl()
|
||||||
|
$context->getTitle()->resetArticleID( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
$context->getOutput()->sendCacheControl();
|
$context->getOutput()->sendCacheControl();
|
||||||
header( "Content-Type: $wgMimeType; charset=UTF-8" );
|
header( "Content-Type: $wgMimeType; charset=UTF-8" );
|
||||||
header( "Content-Language: $wgLanguageCode" );
|
header( "Content-Language: $wgLanguageCode" );
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ class MWExceptionRenderer {
|
||||||
* @param Exception $e
|
* @param Exception $e
|
||||||
* @return string Html to output
|
* @return string Html to output
|
||||||
*/
|
*/
|
||||||
private static function getHTML( Exception $e ) {
|
public static function getHTML( Exception $e ) {
|
||||||
if ( self::showBackTrace( $e ) ) {
|
if ( self::showBackTrace( $e ) ) {
|
||||||
$html = "<div class=\"errorbox\"><p>" .
|
$html = "<div class=\"errorbox\"><p>" .
|
||||||
nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $e ) ) ) .
|
nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $e ) ) ) .
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue