Index: branches/resourceloader/phase3/includes/ResourceLoader.php |
— | — | @@ -84,7 +84,7 @@ |
85 | 85 | protected static function filter( $filter, $data ) { |
86 | 86 | // FIXME: $file is not used by any callers as path rewriting is currently kinda broken |
87 | 87 | global $wgMemc; |
88 | | - $key = wfMemcKey( 'resourceloader', $filter, md5( $data ) ); |
| 88 | + $key = wfMemcKey( 'resourceloader', 'filter', $filter, md5( $data ) ); |
89 | 89 | $cached = $wgMemc->get( $key ); |
90 | 90 | if ( $cached !== false && $cached !== null ) { |
91 | 91 | return $cached; |
Index: branches/resourceloader/phase3/includes/ResourceLoaderModule.php |
— | — | @@ -119,6 +119,9 @@ |
120 | 120 | private $loaders = array(); |
121 | 121 | private $parameters = array(); |
122 | 122 | |
| 123 | + // In-object cache for file dependencies |
| 124 | + private $fileDeps = null; |
| 125 | + |
123 | 126 | /* Public methods */ |
124 | 127 | |
125 | 128 | /** |
— | — | @@ -304,7 +307,29 @@ |
305 | 308 | } |
306 | 309 | |
307 | 310 | public function getStyle( $skin ) { |
308 | | - return $this->getPrimaryStyle() . "\n" . $this->getSkinStyle( $skin ); |
| 311 | + $style = $this->getPrimaryStyle() . "\n" . $this->getSkinStyle( $skin ); |
| 312 | + |
| 313 | + // Extract and store the list of referenced files |
| 314 | + $files = CSSMin::getLocalFileReferences( $style ); |
| 315 | + |
| 316 | + // Only store if modified |
| 317 | + if ( $files !== $this->getFileDependencies( $skin ) ) { |
| 318 | + $encFiles = FormatJson::encode( $files ); |
| 319 | + $dbw = wfGetDb( DB_MASTER ); |
| 320 | + $dbw->replace( 'module_deps', |
| 321 | + array( array( 'md_module', 'md_skin' ) ), array( |
| 322 | + 'md_module' => $this->getName(), |
| 323 | + 'md_skin' => $skin, |
| 324 | + 'md_deps' => $encFiles, |
| 325 | + ) |
| 326 | + ); |
| 327 | + |
| 328 | + // Save into memcached |
| 329 | + global $wgMemc; |
| 330 | + $key = wfMemcKey( 'resourceloader', 'module_deps', $this->getName(), $skin ); |
| 331 | + $wgMemc->set( $key, $encFiles ); |
| 332 | + } |
| 333 | + return $style; |
309 | 334 | } |
310 | 335 | |
311 | 336 | public function getMessages() { |
— | — | @@ -341,7 +366,7 @@ |
342 | 367 | (array)self::getSkinFiles( $skin, $this->skinScripts ), |
343 | 368 | (array)self::getSkinFiles( $skin, $this->skinStyles ), |
344 | 369 | $this->loaders, |
345 | | - $this->getFileDependencies( $lang, $skin ) |
| 370 | + $this->getFileDependencies( $skin ) |
346 | 371 | ); |
347 | 372 | return max( array_map( 'filemtime', $files ) ); |
348 | 373 | } |
— | — | @@ -426,13 +451,30 @@ |
427 | 452 | * @return array of files |
428 | 453 | */ |
429 | 454 | protected function getFileDependencies( $skin ) { |
430 | | - $dbr = wfGetDb( DB_SLAVE ); |
431 | | - $deps = $dbr->selectField( 'module_deps', 'md_deps', array( |
432 | | - 'md_module' => $this->getName(), |
433 | | - 'md_skin' => $skin, |
434 | | - ), __METHOD__ |
435 | | - ); |
436 | | - return $deps ? FormatJson::decode( $deps ) : array(); |
| 455 | + // Try in-object cache first |
| 456 | + if ( !is_null( $this->fileDeps ) ) { |
| 457 | + return $this->fileDeps; |
| 458 | + } |
| 459 | + |
| 460 | + // Now try memcached |
| 461 | + global $wgMemc; |
| 462 | + $key = wfMemcKey( 'resourceloader', 'module_deps', $this->getName(), $skin ); |
| 463 | + $deps = $wgMemc->get( $key ); |
| 464 | + |
| 465 | + if ( !$deps ) { |
| 466 | + $dbr = wfGetDb( DB_SLAVE ); |
| 467 | + $deps = $dbr->selectField( 'module_deps', 'md_deps', array( |
| 468 | + 'md_module' => $this->getName(), |
| 469 | + 'md_skin' => $skin, |
| 470 | + ), __METHOD__ |
| 471 | + ); |
| 472 | + if ( !$deps ) { |
| 473 | + $deps = '[]'; // Empty array so we can do negative caching |
| 474 | + } |
| 475 | + $wgMemc->set( $key, $deps ); |
| 476 | + } |
| 477 | + $this->fileDeps = FormatJson::decode( $deps, true ); |
| 478 | + return $this->fileDeps; |
437 | 479 | } |
438 | 480 | |
439 | 481 | /** |