Skip to content
Snippets Groups Projects
Commit 8bc5040e authored by catch's avatar catch
Browse files

Issue #3415940 by longwave, kristiaanvandeneynde, Spokje: Convert...

Issue #3415940 by longwave, kristiaanvandeneynde, Spokje: Convert CacheTagsInvalidator to use a service collector
parent 75f85d81
No related branches found
No related tags found
No related merge requests found
...@@ -208,12 +208,11 @@ services: ...@@ -208,12 +208,11 @@ services:
arguments: ['@service_container', '%cache_contexts%' ] arguments: ['@service_container', '%cache_contexts%' ]
Drupal\Core\Cache\Context\CacheContextsManager: '@cache_contexts_manager' Drupal\Core\Cache\Context\CacheContextsManager: '@cache_contexts_manager'
cache_tags.invalidator: cache_tags.invalidator:
parent: container.trait
class: Drupal\Core\Cache\CacheTagsInvalidator class: Drupal\Core\Cache\CacheTagsInvalidator
calls:
- [setContainer, ['@service_container']]
tags: tags:
- { name: service_collector, call: addInvalidator, tag: cache_tags_invalidator } - { name: service_collector, call: addInvalidator, tag: cache_tags_invalidator }
- { name: service_collector, call: addBin, tag: cache.bin }
- { name: service_collector, call: addBin, tag: cache.bin.memory }
Drupal\Core\Cache\CacheTagsInvalidatorInterface: '@cache_tags.invalidator' Drupal\Core\Cache\CacheTagsInvalidatorInterface: '@cache_tags.invalidator'
cache_tags.invalidator.checksum: cache_tags.invalidator.checksum:
class: Drupal\Core\Cache\DatabaseCacheTagsChecksum class: Drupal\Core\Cache\DatabaseCacheTagsChecksum
......
...@@ -3,15 +3,12 @@ ...@@ -3,15 +3,12 @@
namespace Drupal\Core\Cache; namespace Drupal\Core\Cache;
use Drupal\Component\Assertion\Inspector; use Drupal\Component\Assertion\Inspector;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
/** /**
* Passes cache tag events to classes that wish to respond to them. * Passes cache tag events to classes that wish to respond to them.
*/ */
class CacheTagsInvalidator implements CacheTagsInvalidatorInterface { class CacheTagsInvalidator implements CacheTagsInvalidatorInterface {
use ContainerAwareTrait;
/** /**
* Holds an array of cache tags invalidators. * Holds an array of cache tags invalidators.
* *
...@@ -19,6 +16,13 @@ class CacheTagsInvalidator implements CacheTagsInvalidatorInterface { ...@@ -19,6 +16,13 @@ class CacheTagsInvalidator implements CacheTagsInvalidatorInterface {
*/ */
protected $invalidators = []; protected $invalidators = [];
/**
* Holds an array of cache bins that support invalidations.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface[]
*/
protected array $bins = [];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -31,7 +35,7 @@ public function invalidateTags(array $tags) { ...@@ -31,7 +35,7 @@ public function invalidateTags(array $tags) {
} }
// Additionally, notify each cache bin if it implements the service. // Additionally, notify each cache bin if it implements the service.
foreach ($this->getInvalidatorCacheBins() as $bin) { foreach ($this->bins as $bin) {
$bin->invalidateTags($tags); $bin->invalidateTags($tags);
} }
} }
...@@ -60,23 +64,15 @@ public function addInvalidator(CacheTagsInvalidatorInterface $invalidator) { ...@@ -60,23 +64,15 @@ public function addInvalidator(CacheTagsInvalidatorInterface $invalidator) {
} }
/** /**
* Returns all cache bins that need to be notified about invalidations. * Adds a cache bin.
* *
* @return \Drupal\Core\Cache\CacheTagsInvalidatorInterface[] * @param \Drupal\Core\Cache\CacheBackendInterface $bin
* An array of cache backend objects that implement the invalidator * A cache bin.
* interface, keyed by their cache bin.
*/ */
protected function getInvalidatorCacheBins() { public function addBin(CacheBackendInterface $bin): void {
$bins = []; if ($bin instanceof CacheTagsInvalidatorInterface) {
foreach (['cache_bins', 'memory_cache_bins'] as $parameter) { $this->bins[] = $bin;
foreach ($this->container->getParameter($parameter) as $service_id => $bin) {
$service = $this->container->get($service_id);
if ($service instanceof CacheTagsInvalidatorInterface) {
$bins[$bin] = $service;
}
}
} }
return $bins;
} }
} }
...@@ -180,7 +180,7 @@ protected function processServiceCollectorPass(array $pass, $consumer_id, Contai ...@@ -180,7 +180,7 @@ protected function processServiceCollectorPass(array $pass, $consumer_id, Contai
foreach ($this->tagCache[$tag] ?? [] as $id => $attributes) { foreach ($this->tagCache[$tag] ?? [] as $id => $attributes) {
// Validate the interface. // Validate the interface.
$handler = $container->getDefinition($id); $handler = $container->getDefinition($id);
if (!is_subclass_of($handler->getClass(), $interface)) { if (!is_a($handler->getClass(), $interface, TRUE)) {
throw new LogicException("Service '$id' for consumer '$consumer_id' does not implement $interface."); throw new LogicException("Service '$id' for consumer '$consumer_id' does not implement $interface.");
} }
$handlers[$id] = $attributes[0]['priority'] ?? 0; $handlers[$id] = $attributes[0]['priority'] ?? 0;
......
...@@ -279,14 +279,6 @@ parameters: ...@@ -279,14 +279,6 @@ parameters:
count: 1 count: 1
path: lib/Drupal/Core/Cache/CacheFactory.php path: lib/Drupal/Core/Cache/CacheFactory.php
-
message: """
#^Usage of deprecated trait Symfony\\\\Component\\\\DependencyInjection\\\\ContainerAwareTrait in class Drupal\\\\Core\\\\Cache\\\\CacheTagsInvalidator\\:
since Symfony 6\\.4, use dependency injection instead$#
"""
count: 1
path: lib/Drupal/Core/Cache/CacheTagsInvalidator.php
- -
message: """ message: """
#^Usage of deprecated trait Symfony\\\\Component\\\\DependencyInjection\\\\ContainerAwareTrait in class Drupal\\\\Core\\\\Cache\\\\ChainedFastBackendFactory\\: #^Usage of deprecated trait Symfony\\\\Component\\\\DependencyInjection\\\\ContainerAwareTrait in class Drupal\\\\Core\\\\Cache\\\\ChainedFastBackendFactory\\:
......
...@@ -4,8 +4,9 @@ ...@@ -4,8 +4,9 @@
namespace Drupal\Tests\Core\Cache; namespace Drupal\Tests\Core\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheTagsInvalidator; use Drupal\Core\Cache\CacheTagsInvalidator;
use Drupal\Core\DependencyInjection\Container; use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
/** /**
...@@ -26,47 +27,32 @@ public function testInvalidateTagsWithInvalidTags() { ...@@ -26,47 +27,32 @@ public function testInvalidateTagsWithInvalidTags() {
/** /**
* @covers ::invalidateTags * @covers ::invalidateTags
* @covers ::addInvalidator * @covers ::addInvalidator
* @covers ::addBin
*/ */
public function testInvalidateTags() { public function testInvalidateTags() {
$cache_tags_invalidator = new CacheTagsInvalidator(); $cache_tags_invalidator = new CacheTagsInvalidator();
// This does not actually implement, $invalidator_cache_bin = $this->createMock(InvalidatingCacheBackendInterface::class);
// \Drupal\Cache\Cache\CacheBackendInterface but we can not mock from two
// interfaces, we would need a test class for that.
$invalidator_cache_bin = $this->createMock('\Drupal\Core\Cache\CacheTagsInvalidator');
$invalidator_cache_bin->expects($this->once()) $invalidator_cache_bin->expects($this->once())
->method('invalidateTags') ->method('invalidateTags')
->with(['node:1']); ->with(['node:1']);
$cache_tags_invalidator->addBin($invalidator_cache_bin);
// We do not have to define that invalidateTags() is never called as the // We do not have to define that invalidateTags() is never called as the
// interface does not define that method, trying to call it would result in // interface does not define that method, trying to call it would result in
// a fatal error. // a fatal error.
$non_invalidator_cache_bin = $this->createMock('\Drupal\Core\Cache\CacheBackendInterface'); $non_invalidator_cache_bin = $this->createMock(CacheBackendInterface::class);
$cache_tags_invalidator->addBin($non_invalidator_cache_bin);
// Repeat the above for memory cache bins. $invalidator = $this->createMock(CacheTagsInvalidatorInterface::class);
$invalidator_memory_cache_bin = $this->createMock('\Drupal\Core\Cache\CacheTagsInvalidator');
$invalidator_memory_cache_bin->expects($this->once())
->method('invalidateTags')
->with(['node:1']);
$non_invalidator_memory_cache_bin = $this->createMock('\Drupal\Core\Cache\CacheBackendInterface');
$container = new Container();
$container->set('cache.invalidator_cache_bin', $invalidator_cache_bin);
$container->set('cache.non_invalidator_cache_bin', $non_invalidator_cache_bin);
$container->set('cache.invalidator_memory_cache_bin', $invalidator_memory_cache_bin);
$container->set('cache.non_invalidator_memory_cache_bin', $non_invalidator_memory_cache_bin);
$container->setParameter('cache_bins', ['cache.invalidator_cache_bin' => 'invalidator_cache_bin', 'cache.non_invalidator_cache_bin' => 'non_invalidator_cache_bin']);
$container->setParameter('memory_cache_bins', ['cache.invalidator_memory_cache_bin' => 'invalidator_memory_cache_bin', 'cache.non_invalidator_memory_cache_bin' => 'non_invalidator_memory_cache_bin']);
$cache_tags_invalidator->setContainer($container);
$invalidator = $this->createMock('\Drupal\Core\Cache\CacheTagsInvalidator');
$invalidator->expects($this->once()) $invalidator->expects($this->once())
->method('invalidateTags') ->method('invalidateTags')
->with(['node:1']); ->with(['node:1']);
$cache_tags_invalidator->addInvalidator($invalidator); $cache_tags_invalidator->addInvalidator($invalidator);
$cache_tags_invalidator->invalidateTags(['node:1']); $cache_tags_invalidator->invalidateTags(['node:1']);
} }
} }
interface InvalidatingCacheBackendInterface extends CacheTagsInvalidatorInterface, CacheBackendInterface {}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment