diff --git a/core/lib/Drupal/Core/Config/CachedStorage.php b/core/lib/Drupal/Core/Config/CachedStorage.php index 7d094b4..8a2844f 100644 --- a/core/lib/Drupal/Core/Config/CachedStorage.php +++ b/core/lib/Drupal/Core/Config/CachedStorage.php @@ -92,6 +92,10 @@ public function write($name, array $data) { return FALSE; } + public function getCache() { + return $this->cache; + } + /** * Implements Drupal\Core\Config\StorageInterface::delete(). */ diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index c0d2617..8c5660d 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -222,6 +222,21 @@ public function get($key = '') { } /** + * Sets the object's data with values loaded from disk. + * + * @param array $data + * The configuration data loaded from disk. + * + * @return Drupal\Core\Config\Config + * The configuration object. + */ + public function preLoad(array $data) { + $this->setData($data); + $this->isNew = FALSE; + return $this; + } + + /** * Replaces the data of this configuration object. * * @param array $data diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 3179b17..3b14ed6 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -52,6 +52,34 @@ class ConfigFactory { protected $cache = array(); /** + * A cache object. + * + * @var Drupal\Core\Cache\CacheBackendInterface + */ + protected $storageCache; + + /** + * The list of cids we preloaded in this request. + * + * @var array + */ + protected $preloadCids = array(); + + /** + * The count of cids we preloaded in __construct(). + * + * @var array + */ + protected $preloadCidsCount = array(); + + /** + * The data we preloaded from preload cids. + * + * @var array + */ + protected $preloadData = array(); + + /** * Constructs the Config factory. * * @param \Drupal\Core\Config\StorageInterface @@ -62,6 +90,21 @@ class ConfigFactory { public function __construct(StorageInterface $storage, ContextInterface $context) { $this->storage = $storage; $this->enterContext($context); + + + if ($this->storage instanceof CachedStorage) { + $this->storageCache = $this->storage->getCache(); + if ($preloadCidsCache = $this->storageCache->get('config:preload:cids')) { + $this->preloadCids = $preloadCidsCache->data; + $this->preloadCidsCount = count($this->preloadCids); + foreach ($this->storageCache->getMultiple($preloadCidsCache->data) as $name => $cacheItem) { + $this->cache[$name] = new Config($name, $this->storage, $this->getContext()); + $this->cache[$name]->init(); + $this->preloadData[$name] = $cacheItem->data; + } + } + drupal_register_shutdown_function(array($this, 'persistPreloadCids')); + } } /** @@ -74,8 +117,15 @@ public function get($name) { $context = $this->getContext(); $cache_key = $this->getCacheKey($name, $context); if (isset($this->cache[$cache_key])) { + if (isset($this->preloadData[$name])) { + $this->cache[$name]->preLoad($this->preloadData[$name]); + unset($this->preloadData[$name]); + } return $this->cache[$cache_key]; } + if (!in_array($name, $this->preloadCids)) { + $this->preloadCids[] = $name; + } $this->cache[$cache_key] = new Config($name, $this->storage, $context); return $this->cache[$cache_key]->init(); @@ -97,11 +147,13 @@ public function reset($name = NULL) { foreach ($this->getCacheKeys($name) as $cache_key) { $this->cache[$cache_key]->init(); } + unset($this->preloadData[$name]); } else { foreach ($this->cache as $config) { $config->init(); } + $this->preloadData = array(); } return $this; } @@ -201,4 +253,10 @@ public function getCacheKeys($name) { return ( strpos($key, $name) !== false ); }); } + + public function persistPreloadCids() { + if ($this->storageCache && count($this->preloadCids) != $this->preloadCidsCount) { + $this->storageCache->set('config:preload:cids', $this->preloadCids); + } + } } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php index 92e4be3..b1d0cf8 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php @@ -372,6 +372,9 @@ public function save(EntityInterface $entity) { drupal_container()->get('config.factory')->rename($prefix . $id, $prefix . $entity->id()); } + // Reset the config factory cache for this object. + drupal_container()->get('config.factory')->reset($prefix . $id); + if (!$is_new && !isset($entity->original)) { $this->resetCache(array($id)); $result = $this->load(array($id)); diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 19c533b..af8c308 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -41,6 +41,7 @@ public function build(ContainerBuilder $container) { $container ->register('config.cachedstorage.storage', 'Drupal\Core\Config\FileStorage') ->addArgument(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY)); + // @todo Replace this with a cache.factory service plus 'config' argument. $container ->register('cache.config', 'Drupal\Core\Cache\CacheBackendInterface') diff --git a/core/modules/system/system.install b/core/modules/system/system.install index e066efb..74c3824 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -684,6 +684,8 @@ function system_schema() { $schema['cache_bootstrap']['description'] = 'Cache table for data required to bootstrap Drupal, may be routed to a shared memory cache.'; $schema['cache_config'] = $schema['cache']; $schema['cache_config']['description'] = 'Cache table for configuration data.'; + $schema['cache_config_preload'] = $schema['cache']; + $schema['cache_config_preload']['description'] = 'Cache table for preload configuration data.'; $schema['cache_form'] = $schema['cache']; $schema['cache_form']['description'] = 'Cache table for the form system to store recently built forms and their storage data, to be used in subsequent page requests.'; $schema['cache_page'] = $schema['cache'];