diff --git a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php index 18d9ae8..a1ecdad 100644 --- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php +++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php @@ -8,6 +8,7 @@ namespace Drupal\Component\Annotation\Plugin\Discovery; use Drupal\Component\Annotation\AnnotationInterface; +use Drupal\Component\Cache\ApcuFileCache; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Component\Annotation\Reflection\MockFileFinder; use Doctrine\Common\Annotations\SimpleAnnotationReader; @@ -100,6 +101,12 @@ public function getDefinitions() { ); foreach ($iterator as $fileinfo) { if ($fileinfo->getExtension() == 'php') { + + if ($cached = ApcuFileCache::get($fileinfo->getPathName())) { + $definitions[$cached['id']] = $cached['content']; + continue; + } + $sub_path = $iterator->getSubIterator()->getSubPath(); $sub_path = $sub_path ? str_replace(DIRECTORY_SEPARATOR, '\\', $sub_path) . '\\' : ''; $class = $namespace . '\\' . $sub_path . $fileinfo->getBasename('.php'); @@ -115,7 +122,10 @@ public function getDefinitions() { $this->prepareAnnotationDefinition($annotation, $class); // AnnotationInterface::get() returns the array definition // instead of requiring us to work with the annotation object. - $definitions[$annotation->getId()] = $annotation->get(); + $id = $annotation->getId(); + $content = $annotation->get(); + $definitions[$id] = $content; + ApcuFileCache::set($fileinfo->getPathName(), ['id' => $id, 'content' => $content]); } } } diff --git a/core/lib/Drupal/Component/Cache/ApcuFileCache.php b/core/lib/Drupal/Component/Cache/ApcuFileCache.php index 0a9d3f8..68d3b85 100644 --- a/core/lib/Drupal/Component/Cache/ApcuFileCache.php +++ b/core/lib/Drupal/Component/Cache/ApcuFileCache.php @@ -28,7 +28,7 @@ class ApcuFileCache { protected static $cached = []; /** - * Gets cached data based on a filename. + * Gets data based on a filename. * * @param string $filepath * Name of the cache that the cached data is based on. @@ -38,22 +38,18 @@ class ApcuFileCache { * or the file has been modified. */ public static function get($filepath) { - // Do nothing if apcu is not available. - if (!function_exists('apc_fetch')) { + if (!file_exists($filepath)) { return NULL; } // Ensure that we cache the full path of the file. $filepath = realpath($filepath); - // Load the data from the static cache or apcu. + // Load the data from the static cache or apcu, if available. if (isset(static::$cached[$filepath])) { $cached = static::$cached[$filepath]; } - else { - if (!file_exists($filepath)) { - return NULL; - } + elseif (!function_exists('apc_fetch')) { $cached = apc_fetch(static::APC_PREFIX . $filepath); if ($cached) { static::$cached[$filepath] = $cached; @@ -68,37 +64,40 @@ public static function get($filepath) { return $cached['data']; } } - } /** - * @param $filepath - * @param $data + * Store data based on a filename. * - * @return null + * @param string $filepath + * Name of the cache that the cached data is based on. + * @param mixed $data + * The data that should be cached. */ public static function set($filepath, $data) { - if (!function_exists('apc_store')) { - return NULL; - } $filepath = realpath($filepath); $cached = [ 'mtime' => filemtime($filepath), 'data' => $data, ]; - apc_store(static::APC_PREFIX . $filepath, $cached); + if (function_exists('apc_store')) { + apc_store(static::APC_PREFIX . $filepath, $cached); + } static::$cached[$filepath] = $cached; - } + /** + * Delete data from the cache. + * + * @param string $filepath + * Name of the cache that the cached data is based on. + */ public static function delete($filepath) { - if (!function_exists('apc_delete')) { - return NULL; - } $filepath = realpath($filepath); - debug($filepath); - apc_delete(static::APC_PREFIX . $filepath); + if (function_exists('apc_delete')) { + apc_delete(static::APC_PREFIX . $filepath); + } unset(static::$cached[$filepath]); } diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php index d4ae53e..796e718 100644 --- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php +++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php @@ -7,6 +7,7 @@ namespace Drupal\Core\DependencyInjection; +use Drupal\Component\Cache\ApcuFileCache; use Drupal\Component\Serialization\Yaml; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -34,15 +35,6 @@ class YamlFileLoader { /** - * Statically cached yaml files. - * - * Especially during tests, YAML files are re-parsed often. - * - * @var array - */ - static protected $yaml = array(); - - /** * @param \Drupal\Core\DependencyInjection\ContainerBuilder $container */ protected $container; @@ -53,24 +45,18 @@ public function __construct(ContainerBuilder $container) } /** - * Resets the internal cache. This method is mostly useful for tests. - */ - public static function reset() - { - static::$yaml = array(); - } - - /** * Loads a Yaml file. * * @param mixed $file The resource */ public function load($file) { - if (!isset(static::$yaml[$file])) { - static::$yaml[$file] = $this->loadFile($file); + // Load from the file cache, fall back to loading the file. + // @todo Refactor this to + $content = ApcuFileCache::get($file); + if (!$content) { + $content = $this->loadFile($file); } - $content = static::$yaml[$file]; // Not supported. //$this->container->addResource(new FileResource($path)); diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php index 9681162..8c4ff31 100644 --- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Extension; +use Drupal\Component\Cache\ApcuFileCache; use Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator; use Drupal\Core\Site\Settings; @@ -359,6 +360,11 @@ protected function scanDirectory($dir, $include_tests) { if (!preg_match(static::PHP_FUNCTION_PATTERN, $fileinfo->getBasename('.info.yml'))) { continue; } + + if ($cached_extension = ApcuFileCache::get($fileinfo->getFileName())) { + $files[$cached_extension->getType()][$key] = $cached_extension; + } + // Determine extension type from info file. $type = FALSE; $file = $fileinfo->openFile('r'); @@ -394,6 +400,7 @@ protected function scanDirectory($dir, $include_tests) { $extension->origin = $dir; $files[$type][$key] = $extension; + ApcuFileCache::set($fileinfo->getFileName(), $extension); } return $files; } diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 1f62ef4..0f1816e 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -1026,9 +1026,6 @@ protected function setContainerParameter($name, $value) { $services = Yaml::decode(file_get_contents($filename)); $services['parameters'][$name] = $value; file_put_contents($filename, Yaml::encode($services)); - - // Clear the YML file cache. - YamlFileLoader::reset(); } /**