if ( !$options['cache'] ) {
$result = $this->applyFilter( $filter, $data );
} else {
- $key = wfMemcKey( 'resourceloader', 'filter', $filter, self::$filterCacheVersion, md5( $data ) );
+ $key = wfGlobalCacheKey( 'resourceloader', 'filter', $filter, self::$filterCacheVersion, md5( $data ) );
$cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
$cacheEntry = $cache->get( $key );
if ( is_string( $cacheEntry ) ) {
}
$result = '';
try {
- wfIncrStats( "resourceloader_cache.$filter.miss" );
+ $stats = RequestContext::getMain()->getStats();
+ $statStart = microtime( true );
+
$result = $this->applyFilter( $filter, $data );
+
+ $stats->timing( "resourceloader_cache.$filter.miss", microtime( true ) - $statStart );
if ( $options['cacheReport'] ) {
$result .= "\n/* cache key: $key */";
}
- $cache->set( $key, $result );
+ // Set a TTL since HHVM's APC doesn't have any limitation or eviction logic.
+ $cache->set( $key, $result, 24 * 3600 );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
$this->logger->warning( 'Minification failed: {exception}', array(
}
private function applyFilter( $filter, $data ) {
- switch ( $filter ) {
- case 'minify-js':
- return JavaScriptMinifier::minify( $data,
- $this->config->get( 'ResourceLoaderMinifierStatementsOnOwnLine' ),
- $this->config->get( 'ResourceLoaderMinifierMaxLineLength' )
- );
- case 'minify-css':
- return CSSMin::minify( $data );
- }
- return $data;
+ switch ( $filter ) {
+ case 'minify-js':
+ return JavaScriptMinifier::minify( $data,
+ $this->config->get( 'ResourceLoaderMinifierStatementsOnOwnLine' ),
+ $this->config->get( 'ResourceLoaderMinifierMaxLineLength' )
+ );
+ case 'minify-css':
+ return CSSMin::minify( $data );
+ }
+
+ return $data;
}
/* Methods */
header( 'Cache-Control: private, no-cache, must-revalidate' );
header( 'Pragma: no-cache' );
} else {
- header( "Cache-Control: public, max-age=$maxage, s-maxage=$smaxage" );
+ header( "Cache-Control: public, must-revalidate, max-age=$maxage, s-maxage=$smaxage" );
$exp = min( $maxage, $smaxage );
header( 'Expires: ' . wfTimestamp( TS_RFC2822, $exp + time() ) );
}
+
+ // Send the current time expressed as fractional seconds since epoch,
+ // with microsecond precision. This helps distinguish hits from misses
+ // in edge caches.
+ header( 'MediaWiki-Timestamp: ' . microtime( true ) );
}
/**
$name, $scripts, $styles, $messages, $templates
) {
if ( is_string( $scripts ) ) {
- $scripts = new XmlJsCode( "function ( $, jQuery ) {\n{$scripts}\n}" );
+ // Site and user module are a legacy scripts that run in the global scope (no closure).
+ // Transportation as string instructs mw.loader.implement to use globalEval.
+ if ( $name !== 'site' && $name !== 'user' ) {
+ $scripts = new XmlJsCode( "function ( $, jQuery ) {\n{$scripts}\n}" );
+ }
} elseif ( !is_array( $scripts ) ) {
throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
}
$module = array(
$name,
$scripts,
- (object) $styles,
- (object) $messages,
- (object) $templates,
+ (object)$styles,
+ (object)$messages,
+ (object)$templates,
);
self::trimArray( $module );