From ef79d8361e24daf390fd9f5decf9e9a8137fbc18 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Thu, 14 May 2015 19:54:39 +0100 Subject: [PATCH] cache: Add in-process caching to MessageBlobStore This allows us to continue to use MessageBlobStore::get() as a way to pre-fetch messages in batches for multiple modules while also allowing individual modules to retrieve their messages in a convenient way. This is in preparation for implementing ResourceLoaderModule::buildContents and using it in ResourceLoaderModule::getVersionHash. ResourceLoader::respond() already fetches message blobs in batches for the actual response, but it also needs getVersionHash(), which would otherwise fetch the same messages a second time. Change-Id: I7e4c8b65765b54807123e85cfbb7eb2e5b2f39bd --- includes/cache/MessageBlobStore.php | 45 +++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/includes/cache/MessageBlobStore.php b/includes/cache/MessageBlobStore.php index 011cae6629..19349b2d6a 100644 --- a/includes/cache/MessageBlobStore.php +++ b/includes/cache/MessageBlobStore.php @@ -32,6 +32,15 @@ * constituent messages or the resource itself is changed. */ class MessageBlobStore { + /** + * In-process cache for message blobs. + * + * Keyed by language code, then module name. + * + * @var array + */ + protected $blobCache = array(); + /** * Get the singleton instance * @@ -56,18 +65,40 @@ class MessageBlobStore { if ( !count( $modules ) ) { return array(); } - // Try getting from the DB first - $blobs = $this->getFromDB( $resourceLoader, array_keys( $modules ), $lang ); - // Generate blobs for any missing modules and store them in the DB - $missing = array_diff( array_keys( $modules ), array_keys( $blobs ) ); - foreach ( $missing as $name ) { + $blobs = array(); + + // Try in-process cache + $missingFromCache = array(); + foreach ( $modules as $name => $module ) { + if ( isset( $this->blobCache[$lang][$name] ) ) { + $blobs[$name] = $this->blobCache[$lang][$name]; + } else { + $missingFromCache[] = $name; + } + } + + // Try DB cache + if ( $missingFromCache ) { + $blobs += $this->getFromDB( $resourceLoader, $missingFromCache, $lang ); + } + + // Generate new blobs for any remaining modules and store in DB + $missingFromDb = array_diff( array_keys( $modules ), array_keys( $blobs ) ); + foreach ( $missingFromDb as $name ) { $blob = $this->insertMessageBlob( $name, $modules[$name], $lang ); if ( $blob ) { $blobs[$name] = $blob; } } + // Update in-process cache + if ( isset( $this->blobCache[$lang] ) ) { + $this->blobCache[$lang] += $blobs; + } else { + $this->blobCache[$lang] = $blobs; + } + return $blobs; } @@ -339,6 +370,10 @@ class MessageBlobStore { * @return array Array mapping module names to blobs */ private function getFromDB( ResourceLoader $resourceLoader, $modules, $lang ) { + if ( !count( $modules ) ) { + return array(); + } + $config = $resourceLoader->getConfig(); $retval = array(); $dbr = wfGetDB( DB_SLAVE ); -- 2.20.1