Commit 8ec847cc authored by catch's avatar catch

Issue #1786490 by Berdir, amateescu, damiankloip, dawehner: Add caching to the state system.

parent 4b7da9ab
...@@ -137,10 +137,10 @@ services: ...@@ -137,10 +137,10 @@ services:
factory_class: Drupal\Component\Utility\Settings factory_class: Drupal\Component\Utility\Settings
factory_method: getSingleton factory_method: getSingleton
state: state:
class: Drupal\Core\KeyValueStore\KeyValueStoreInterface class: Drupal\Core\KeyValueStore\State
factory_method: get arguments: ['@keyvalue']
factory_service: keyvalue tags:
arguments: [state] - { name: persist }
queue: queue:
class: Drupal\Core\Queue\QueueFactory class: Drupal\Core\Queue\QueueFactory
arguments: ['@settings'] arguments: ['@settings']
......
...@@ -456,10 +456,8 @@ function install_begin_request(&$install_state) { ...@@ -456,10 +456,8 @@ function install_begin_request(&$install_state) {
$settings['keyvalue_default'] = 'keyvalue.memory'; $settings['keyvalue_default'] = 'keyvalue.memory';
new Settings($settings); new Settings($settings);
$container->register('state', 'Drupal\Core\KeyValueStore\KeyValueStoreInterface') $container->register('state', 'Drupal\Core\KeyValueStore\State')
->setFactoryService(new Reference('keyvalue')) ->addArgument(new Reference('keyvalue'));
->setFactoryMethod('get')
->addArgument('state');
// Register Twig template engine for use during install. // Register Twig template engine for use during install.
CoreServiceProvider::registerTwig($container); CoreServiceProvider::registerTwig($container);
......
...@@ -288,7 +288,7 @@ public static function keyValue($collection) { ...@@ -288,7 +288,7 @@ public static function keyValue($collection) {
* needs to be the same across development, production, etc. environments * needs to be the same across development, production, etc. environments
* (for example, the system maintenance message) should use \Drupal::config() instead. * (for example, the system maintenance message) should use \Drupal::config() instead.
* *
* @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @return \Drupal\Core\KeyValueStore\StateInterface
*/ */
public static function state() { public static function state() {
return static::$container->get('state'); return static::$container->get('state');
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
namespace Drupal\Core\Asset; namespace Drupal\Core\Asset;
use Drupal\Core\Asset\AssetCollectionOptimizerInterface; use Drupal\Core\KeyValueStore\StateInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
/** /**
* Optimizes CSS assets. * Optimizes CSS assets.
...@@ -38,7 +37,7 @@ class CssCollectionOptimizer implements AssetCollectionOptimizerInterface { ...@@ -38,7 +37,7 @@ class CssCollectionOptimizer implements AssetCollectionOptimizerInterface {
/** /**
* The state key/value store. * The state key/value store.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state; protected $state;
...@@ -51,10 +50,10 @@ class CssCollectionOptimizer implements AssetCollectionOptimizerInterface { ...@@ -51,10 +50,10 @@ class CssCollectionOptimizer implements AssetCollectionOptimizerInterface {
* The optimizer for a single CSS asset. * The optimizer for a single CSS asset.
* @param \Drupal\Core\Asset\AssetDumperInterface * @param \Drupal\Core\Asset\AssetDumperInterface
* The dumper for optimized CSS assets. * The dumper for optimized CSS assets.
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @param \Drupal\Core\KeyValueStore\StateInterface
* The state key/value store. * The state key/value store.
*/ */
public function __construct(AssetCollectionGrouperInterface $grouper, AssetOptimizerInterface $optimizer, AssetDumperInterface $dumper, KeyValueStoreInterface $state) { public function __construct(AssetCollectionGrouperInterface $grouper, AssetOptimizerInterface $optimizer, AssetDumperInterface $dumper, StateInterface $state) {
$this->grouper = $grouper; $this->grouper = $grouper;
$this->optimizer = $optimizer; $this->optimizer = $optimizer;
$this->dumper = $dumper; $this->dumper = $dumper;
......
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
namespace Drupal\Core\Asset; namespace Drupal\Core\Asset;
use Drupal\Core\Asset\AssetCollectionRendererInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Core\KeyValueStore\StateInterface;
/** /**
* Renders CSS assets. * Renders CSS assets.
...@@ -18,17 +17,17 @@ class CssCollectionRenderer implements AssetCollectionRendererInterface { ...@@ -18,17 +17,17 @@ class CssCollectionRenderer implements AssetCollectionRendererInterface {
/** /**
* The state key/value store. * The state key/value store.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state; protected $state;
/** /**
* Constructs a CssCollectionRenderer. * Constructs a CssCollectionRenderer.
* *
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @param \Drupal\Core\KeyValueStore\StateInterface
* The state key/value store. * The state key/value store.
*/ */
public function __construct(KeyValueStoreInterface $state) { public function __construct(StateInterface $state) {
$this->state = $state; $this->state = $state;
} }
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
namespace Drupal\Core\Asset; namespace Drupal\Core\Asset;
use Drupal\Core\Asset\AssetCollectionOptimizerInterface; use Drupal\Core\KeyValueStore\StateInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
/** /**
...@@ -39,7 +38,7 @@ class JsCollectionOptimizer implements AssetCollectionOptimizerInterface { ...@@ -39,7 +38,7 @@ class JsCollectionOptimizer implements AssetCollectionOptimizerInterface {
/** /**
* The state key/value store. * The state key/value store.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state; protected $state;
...@@ -52,10 +51,10 @@ class JsCollectionOptimizer implements AssetCollectionOptimizerInterface { ...@@ -52,10 +51,10 @@ class JsCollectionOptimizer implements AssetCollectionOptimizerInterface {
* The optimizer for a single JS asset. * The optimizer for a single JS asset.
* @param \Drupal\Core\Asset\AssetDumperInterface * @param \Drupal\Core\Asset\AssetDumperInterface
* The dumper for optimized JS assets. * The dumper for optimized JS assets.
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @param \Drupal\Core\KeyValueStore\StateInterface
* The state key/value store. * The state key/value store.
*/ */
public function __construct(AssetCollectionGrouperInterface $grouper, AssetOptimizerInterface $optimizer, AssetDumperInterface $dumper, KeyValueStoreInterface $state) { public function __construct(AssetCollectionGrouperInterface $grouper, AssetOptimizerInterface $optimizer, AssetDumperInterface $dumper, StateInterface $state) {
$this->grouper = $grouper; $this->grouper = $grouper;
$this->optimizer = $optimizer; $this->optimizer = $optimizer;
$this->dumper = $dumper; $this->dumper = $dumper;
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
namespace Drupal\Core\Asset; namespace Drupal\Core\Asset;
use Drupal\Core\Asset\AssetCollectionRendererInterface; use Drupal\Core\KeyValueStore\StateInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
/** /**
* Renders JavaScript assets. * Renders JavaScript assets.
...@@ -17,17 +16,17 @@ class JsCollectionRenderer implements AssetCollectionRendererInterface { ...@@ -17,17 +16,17 @@ class JsCollectionRenderer implements AssetCollectionRendererInterface {
/** /**
* The state key/value store. * The state key/value store.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state; protected $state;
/** /**
* Constructs a CssCollectionRenderer. * Constructs a CssCollectionRenderer.
* *
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @param \Drupal\Core\KeyValueStore\StateInterface
* The state key/value store. * The state key/value store.
*/ */
public function __construct(KeyValueStoreInterface $state) { public function __construct(StateInterface $state) {
$this->state = $state; $this->state = $state;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
namespace Drupal\Core\Extension; namespace Drupal\Core\Extension;
use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\KeyValueStore\StateInterface;
/** /**
* Class that manages enabled modules in a Drupal installation. * Class that manages enabled modules in a Drupal installation.
...@@ -18,7 +18,7 @@ class CachedModuleHandler extends ModuleHandler implements CachedModuleHandlerIn ...@@ -18,7 +18,7 @@ class CachedModuleHandler extends ModuleHandler implements CachedModuleHandlerIn
/** /**
* State key/value store. * State key/value store.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state; protected $state;
...@@ -39,7 +39,7 @@ class CachedModuleHandler extends ModuleHandler implements CachedModuleHandlerIn ...@@ -39,7 +39,7 @@ class CachedModuleHandler extends ModuleHandler implements CachedModuleHandlerIn
/** /**
* Constructs a new CachedModuleHandler object. * Constructs a new CachedModuleHandler object.
*/ */
public function __construct(array $module_list = array(), KeyValueStoreInterface $state, CacheBackendInterface $bootstrap_cache) { public function __construct(array $module_list = array(), StateInterface $state, CacheBackendInterface $bootstrap_cache) {
parent::__construct($module_list); parent::__construct($module_list);
$this->state = $state; $this->state = $state;
$this->bootstrapCache = $bootstrap_cache; $this->bootstrapCache = $bootstrap_cache;
......
<?php
/**
* @file
* Contains Drupal\Core\KeyValueStore\StateInterface.
*/
namespace Drupal\Core\KeyValueStore;
/**
* Provides the state system using a key value store.
*/
class State implements StateInterface {
/**
* The key value store to use.
*
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
*/
protected $keyValueStore;
/**
* Static state cache.
*
* @var array
*/
protected $cache = array();
/**
* Constructs a State object.
*
* @param \Drupal\Core\KeyValueStore\KeyValueFactory $key_value_factory
* The key value store to use.
*/
function __construct(KeyValueFactory $key_value_factory) {
$this->keyValueStore = $key_value_factory->get('state');
}
/**
* {@inheritdoc}
*/
public function get($key, $default = NULL) {
$values = $this->getMultiple(array($key));
return isset($values[$key]) ? $values[$key] : $default;
}
/**
* {@inheritdoc}
*/
public function getMultiple(array $keys) {
$values = array();
$load = array();
foreach ($keys as $key) {
// Check if we have a value in the cache.
if (isset($this->cache[$key])) {
$values[$key] = $this->cache[$key];
}
// Load the value if we don't have an explicit NULL value.
elseif (!array_key_exists($key, $this->cache)) {
$load[] = $key;
}
}
if ($load) {
$loaded_values = $this->keyValueStore->getMultiple($load);
foreach ($load as $key) {
// If we find a value, even one that is NULL, add it to the cache and
// return it.
if (isset($loaded_values[$key]) || array_key_exists($key, $loaded_values)) {
$values[$key] = $loaded_values[$key];
$this->cache[$key] = $loaded_values[$key];
}
else {
$this->cache[$key] = NULL;
}
}
}
return $values;
}
/**
* {@inheritdoc}
*/
public function set($key, $value) {
$this->cache[$key] = $value;
$this->keyValueStore->set($key, $value);
}
/**
* {@inheritdoc}
*/
public function setMultiple(array $data) {
foreach ($data as $key => $value) {
$this->cache[$key] = $value;
}
$this->keyValueStore->setMultiple($data);
}
/**
* {@inheritdoc}
*/
public function delete($key) {
$this->deleteMultiple(array($key));
}
/**
* {@inheritdoc}
*/
public function deleteMultiple(array $keys) {
foreach ($keys as $key) {
unset($this->cache[$key]);
}
$this->keyValueStore->deleteMultiple($keys);
}
/**
* {@inheritdoc}
*/
public function resetCache() {
$this->cache = array();
}
}
<?php
/**
* @file
* Contains Drupal\Core\KeyValueStore\StateInterface.
*/
namespace Drupal\Core\KeyValueStore;
/**
* Defines the interface for the state system.
*/
interface StateInterface {
/**
* Returns the stored value for a given key.
*
* @param string $key
* The key of the data to retrieve.
* @param mixed $default
* The default value to use if the key is not found.
*
* @return mixed
* The stored value, or NULL if no value exists.
*/
public function get($key, $default = NULL);
/**
* Returns the stored key/value pairs for a given set of keys.
*
* @param array $keys
* A list of keys to retrieve.
*
* @return array
* An associative array of items successfully returned, indexed by key.
*/
public function getMultiple(array $keys);
/**
* Saves a value for a given key.
*
* @param string $key
* The key of the data to store.
* @param mixed $value
* The data to store.
*/
public function set($key, $value);
/**
* Saves key/value pairs.
*
* @param array $data
* An associative array of key/value pairs.
*/
public function setMultiple(array $data);
/**
* Deletes an item.
*
* @param string $key
* The item name to delete.
*/
public function delete($key);
/**
* Deletes multiple items.
*
* @param array $keys
* A list of item names to delete.
*/
public function deleteMultiple(array $keys);
/**
* Resets the static cache.
*
* This is mainly used in testing environments.
*/
public function resetCache();
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
use Drupal\Component\Utility\MapArray; use Drupal\Component\Utility\MapArray;
use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\KeyValueStore\StateInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
...@@ -27,7 +27,7 @@ class LanguageManager { ...@@ -27,7 +27,7 @@ class LanguageManager {
/** /**
* The Key/Value Store to use for state. * The Key/Value Store to use for state.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state = NULL; protected $state = NULL;
...@@ -65,12 +65,12 @@ class LanguageManager { ...@@ -65,12 +65,12 @@ class LanguageManager {
/** /**
* Constructs an LanguageManager object. * Constructs an LanguageManager object.
* *
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state * @param \Drupal\Core\KeyValueStore\StateInterface $state
* (optional) The state keyvalue store. Defaults to NULL. * (optional) The state keyvalue store. Defaults to NULL.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* (optional) The module handler service. Defaults to NULL. * (optional) The module handler service. Defaults to NULL.
*/ */
public function __construct(KeyValueStoreInterface $state = NULL, ModuleHandlerInterface $module_handler = NULL) { public function __construct(StateInterface $state = NULL, ModuleHandlerInterface $module_handler = NULL) {
$this->state = $state; $this->state = $state;
$this->moduleHandler = $module_handler; $this->moduleHandler = $module_handler;
} }
......
...@@ -20,13 +20,6 @@ class AliasManager implements AliasManagerInterface { ...@@ -20,13 +20,6 @@ class AliasManager implements AliasManagerInterface {
*/ */
protected $connection; protected $connection;
/**
* The Key/Value Store to use for state
*
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
*/
protected $state;
/** /**
* Language manager for retrieving the default langcode when none is specified. * Language manager for retrieving the default langcode when none is specified.
* *
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
use Drupal\Core\Cache\CacheCollector; use Drupal\Core\Cache\CacheCollector;
use Drupal\Core\Database\Connection; use Drupal\Core\Database\Connection;
use Drupal\Core\DestructableInterface; use Drupal\Core\DestructableInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\KeyValueStore\StateInterface;
use Drupal\Core\Lock\LockBackendInterface; use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Utility\CacheArray; use Drupal\Core\Utility\CacheArray;
...@@ -23,7 +23,7 @@ class AliasWhitelist extends CacheCollector { ...@@ -23,7 +23,7 @@ class AliasWhitelist extends CacheCollector {
/** /**
* The Key/Value Store to use for state. * The Key/Value Store to use for state.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface
*/ */
protected $state; protected $state;
...@@ -43,12 +43,12 @@ class AliasWhitelist extends CacheCollector { ...@@ -43,12 +43,12 @@ class AliasWhitelist extends CacheCollector {
* The cache backend. * The cache backend.
* @param \Drupal\Core\Lock\LockBackendInterface $lock * @param \Drupal\Core\Lock\LockBackendInterface $lock
* The lock backend. * The lock backend.
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state * @param \Drupal\Core\KeyValueStore\StateInterface $state
* The state keyvalue store. * The state keyvalue store.
* @param \Drupal\Core\Database\Connection $connection * @param \Drupal\Core\Database\Connection $connection
* The database connection. * The database connection.
*/ */
public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, KeyValueStoreInterface $state, Connection $connection) { public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, Connection $connection) {
parent::__construct($cid, $cache, $lock); parent::__construct($cid, $cache, $lock);
$this->state = $state; $this->state = $state;
$this->connection = $connection; $this->connection = $connection;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
namespace Drupal\Core; namespace Drupal\Core;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\KeyValueStore\StateInterface;
use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\Crypt;
/** /**
...@@ -18,17 +18,17 @@ class PrivateKey { ...@@ -18,17 +18,17 @@ class PrivateKey {
/** /**
* The state service. * The state service.
* *
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface * @var \Drupal\Core\KeyValueStore\StateInterface