Loading core/core.services.yml +6 −0 Original line number Diff line number Diff line Loading @@ -328,6 +328,12 @@ services: - { name: cache.bin, default_backend: cache.backend.chainedfast } factory: ['@cache_factory', 'get'] arguments: [discovery] cache_prewarmer: class: Drupal\Core\PreWarm\CachePreWarmer arguments: ['@class_resolver'] tags: - { name: service_id_collector, tag: cache_prewarmable } Drupal\Core\PreWarm\CachePreWarmerInterface: '@cache_prewarmer' variation_cache.access_policy: class: Drupal\Core\Cache\VariationCacheInterface factory: ['@variation_cache_factory', 'get'] Loading core/lib/Drupal/Core/CoreServiceProvider.php +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ use Drupal\Core\DependencyInjection\ServiceProviderInterface; use Drupal\Core\Extension\ModuleUninstallValidatorInterface; use Drupal\Core\Plugin\PluginManagerPass; use Drupal\Core\PreWarm\PreWarmableInterface; use Drupal\Core\Queue\QueueFactoryInterface; use Drupal\Core\Render\MainContent\MainContentRenderersPass; use Drupal\Core\Site\Settings; Loading Loading @@ -123,6 +124,9 @@ public function register(ContainerBuilder $container) { $container->registerForAutoconfiguration(QueueFactoryInterface::class) ->addTag('queue_factory'); $container->registerForAutoconfiguration(PreWarmableInterface::class) ->addTag('cache_prewarmable'); $container->registerForAutoconfiguration(ModuleUninstallValidatorInterface::class) ->addTag('module_install.uninstall_validator'); Loading core/lib/Drupal/Core/Entity/EntityFieldManager.php +9 −1 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ use Drupal\Core\Field\FieldDefinition; use Drupal\Core\KeyValueStore\KeyValueFactoryInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\PreWarm\PreWarmableInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\TypedDataManagerInterface; Loading @@ -20,7 +21,7 @@ * This includes field definitions, base field definitions, and field storage * definitions. */ class EntityFieldManager implements EntityFieldManagerInterface { class EntityFieldManager implements EntityFieldManagerInterface, PreWarmableInterface { use UseCacheBackendTrait; use StringTranslationTrait; Loading Loading @@ -697,6 +698,13 @@ protected function loadExtraFields(): array { return $extra; } /** * {@inheritdoc} */ public function preWarm(): void { $this->getFieldMap(); } /** * {@inheritdoc} */ Loading core/lib/Drupal/Core/Plugin/PreWarmablePluginManagerTrait.php 0 → 100644 +24 −0 Original line number Diff line number Diff line <?php namespace Drupal\Core\Plugin; /** * Provides a trait for Drupal\Core\PreWarm\PreWarmableInterface. * * For the vast majority of plugin managers, the ::getDefinitions() method does * exactly the right logic for cache prewarming, so this provides a default * implementation that uses that. * * @phpstan-require-implements \Drupal\Component\Plugin\Discovery\DiscoveryInterface * @phpstan-require-implements \Drupal\Core\PreWarm\PreWarmableInterface */ trait PreWarmablePluginManagerTrait { /** * Implements \Drupal\Core\PreWarm\PreWarmableInterface. */ public function preWarm(): void { $this->getDefinitions(); } } core/lib/Drupal/Core/PreWarm/CachePreWarmer.php 0 → 100644 +80 −0 Original line number Diff line number Diff line <?php namespace Drupal\Core\PreWarm; use Drupal\Core\DependencyInjection\ClassResolverInterface; // cspell:ignore ABCDEF FCDABE BEDAFC /** * Prewarms caches for services that implement PreWarmableInterface. * * Takes a list of prewarmable services and prewarms them at random. * Randomization is used because whenever two or more requests are building * caches, the most benefit is gained by minimizing duplication. For example * two requests rely on the same six services but these services are requested * at different times, one request builds caches for the other and vice versa. * * No randomization: * * ABCDEF * ABCDEF * * Randomization: * * ABCDEF * FCDABE * * Randomization and three requests: * * ABCDEF * FCDABE * BEDAFC * * @internal * * @see Drupal\Core\PreWarm\PreWarmableInterface * @see Drupal\Core\DrupalKernel::handle() * @see Drupal\Core\LockBackendAbstract::wait() * @see Drupal\Core\Routing\RouteProvider::preLoadRoutes() */ class CachePreWarmer implements CachePreWarmerInterface { /** * Whether to prewarm caches at the end of the request. */ protected bool $needsPreWarming = FALSE; public function __construct( protected readonly ClassResolverInterface $classResolver, protected array $serviceIds, ) { // Ensure the serviceId order is random to reduce chances of conflicts. shuffle($this->serviceIds); } /** * {@inheritdoc} */ public function preWarmOneCache(): bool { $candidate = array_pop($this->serviceIds); if ($candidate === NULL) { return FALSE; } $service = $this->classResolver->getInstanceFromDefinition($candidate); $service->preWarm(); return TRUE; } /** * {@inheritdoc} */ public function preWarmAllCaches(): bool { $prewarmed = FALSE; while ($this->preWarmOneCache()) { $prewarmed = TRUE; } return $prewarmed; } } Loading
core/core.services.yml +6 −0 Original line number Diff line number Diff line Loading @@ -328,6 +328,12 @@ services: - { name: cache.bin, default_backend: cache.backend.chainedfast } factory: ['@cache_factory', 'get'] arguments: [discovery] cache_prewarmer: class: Drupal\Core\PreWarm\CachePreWarmer arguments: ['@class_resolver'] tags: - { name: service_id_collector, tag: cache_prewarmable } Drupal\Core\PreWarm\CachePreWarmerInterface: '@cache_prewarmer' variation_cache.access_policy: class: Drupal\Core\Cache\VariationCacheInterface factory: ['@variation_cache_factory', 'get'] Loading
core/lib/Drupal/Core/CoreServiceProvider.php +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ use Drupal\Core\DependencyInjection\ServiceProviderInterface; use Drupal\Core\Extension\ModuleUninstallValidatorInterface; use Drupal\Core\Plugin\PluginManagerPass; use Drupal\Core\PreWarm\PreWarmableInterface; use Drupal\Core\Queue\QueueFactoryInterface; use Drupal\Core\Render\MainContent\MainContentRenderersPass; use Drupal\Core\Site\Settings; Loading Loading @@ -123,6 +124,9 @@ public function register(ContainerBuilder $container) { $container->registerForAutoconfiguration(QueueFactoryInterface::class) ->addTag('queue_factory'); $container->registerForAutoconfiguration(PreWarmableInterface::class) ->addTag('cache_prewarmable'); $container->registerForAutoconfiguration(ModuleUninstallValidatorInterface::class) ->addTag('module_install.uninstall_validator'); Loading
core/lib/Drupal/Core/Entity/EntityFieldManager.php +9 −1 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ use Drupal\Core\Field\FieldDefinition; use Drupal\Core\KeyValueStore\KeyValueFactoryInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\PreWarm\PreWarmableInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\TypedDataManagerInterface; Loading @@ -20,7 +21,7 @@ * This includes field definitions, base field definitions, and field storage * definitions. */ class EntityFieldManager implements EntityFieldManagerInterface { class EntityFieldManager implements EntityFieldManagerInterface, PreWarmableInterface { use UseCacheBackendTrait; use StringTranslationTrait; Loading Loading @@ -697,6 +698,13 @@ protected function loadExtraFields(): array { return $extra; } /** * {@inheritdoc} */ public function preWarm(): void { $this->getFieldMap(); } /** * {@inheritdoc} */ Loading
core/lib/Drupal/Core/Plugin/PreWarmablePluginManagerTrait.php 0 → 100644 +24 −0 Original line number Diff line number Diff line <?php namespace Drupal\Core\Plugin; /** * Provides a trait for Drupal\Core\PreWarm\PreWarmableInterface. * * For the vast majority of plugin managers, the ::getDefinitions() method does * exactly the right logic for cache prewarming, so this provides a default * implementation that uses that. * * @phpstan-require-implements \Drupal\Component\Plugin\Discovery\DiscoveryInterface * @phpstan-require-implements \Drupal\Core\PreWarm\PreWarmableInterface */ trait PreWarmablePluginManagerTrait { /** * Implements \Drupal\Core\PreWarm\PreWarmableInterface. */ public function preWarm(): void { $this->getDefinitions(); } }
core/lib/Drupal/Core/PreWarm/CachePreWarmer.php 0 → 100644 +80 −0 Original line number Diff line number Diff line <?php namespace Drupal\Core\PreWarm; use Drupal\Core\DependencyInjection\ClassResolverInterface; // cspell:ignore ABCDEF FCDABE BEDAFC /** * Prewarms caches for services that implement PreWarmableInterface. * * Takes a list of prewarmable services and prewarms them at random. * Randomization is used because whenever two or more requests are building * caches, the most benefit is gained by minimizing duplication. For example * two requests rely on the same six services but these services are requested * at different times, one request builds caches for the other and vice versa. * * No randomization: * * ABCDEF * ABCDEF * * Randomization: * * ABCDEF * FCDABE * * Randomization and three requests: * * ABCDEF * FCDABE * BEDAFC * * @internal * * @see Drupal\Core\PreWarm\PreWarmableInterface * @see Drupal\Core\DrupalKernel::handle() * @see Drupal\Core\LockBackendAbstract::wait() * @see Drupal\Core\Routing\RouteProvider::preLoadRoutes() */ class CachePreWarmer implements CachePreWarmerInterface { /** * Whether to prewarm caches at the end of the request. */ protected bool $needsPreWarming = FALSE; public function __construct( protected readonly ClassResolverInterface $classResolver, protected array $serviceIds, ) { // Ensure the serviceId order is random to reduce chances of conflicts. shuffle($this->serviceIds); } /** * {@inheritdoc} */ public function preWarmOneCache(): bool { $candidate = array_pop($this->serviceIds); if ($candidate === NULL) { return FALSE; } $service = $this->classResolver->getInstanceFromDefinition($candidate); $service->preWarm(); return TRUE; } /** * {@inheritdoc} */ public function preWarmAllCaches(): bool { $prewarmed = FALSE; while ($this->preWarmOneCache()) { $prewarmed = TRUE; } return $prewarmed; } }