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:
arguments: ['@service_container', '%cache_contexts%' ]
Drupal\Core\Cache\Context\CacheContextsManager: '@cache_contexts_manager'
cache_tags.invalidator:
parent: container.trait
class: Drupal\Core\Cache\CacheTagsInvalidator
calls:
- [setContainer, ['@service_container']]
tags:
- { 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'
cache_tags.invalidator.checksum:
class: Drupal\Core\Cache\DatabaseCacheTagsChecksum
......
......@@ -3,15 +3,12 @@
namespace Drupal\Core\Cache;
use Drupal\Component\Assertion\Inspector;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
/**
* Passes cache tag events to classes that wish to respond to them.
*/
class CacheTagsInvalidator implements CacheTagsInvalidatorInterface {
use ContainerAwareTrait;
/**
* Holds an array of cache tags invalidators.
*
......@@ -19,6 +16,13 @@ class CacheTagsInvalidator implements CacheTagsInvalidatorInterface {
*/
protected $invalidators = [];
/**
* Holds an array of cache bins that support invalidations.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface[]
*/
protected array $bins = [];
/**
* {@inheritdoc}
*/
......@@ -31,7 +35,7 @@ public function invalidateTags(array $tags) {
}
// Additionally, notify each cache bin if it implements the service.
foreach ($this->getInvalidatorCacheBins() as $bin) {
foreach ($this->bins as $bin) {
$bin->invalidateTags($tags);
}
}
......@@ -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[]
* An array of cache backend objects that implement the invalidator
* interface, keyed by their cache bin.
* @param \Drupal\Core\Cache\CacheBackendInterface $bin
* A cache bin.
*/
protected function getInvalidatorCacheBins() {
$bins = [];
foreach (['cache_bins', 'memory_cache_bins'] as $parameter) {
foreach ($this->container->getParameter($parameter) as $service_id => $bin) {
$service = $this->container->get($service_id);
if ($service instanceof CacheTagsInvalidatorInterface) {
$bins[$bin] = $service;
}
}
public function addBin(CacheBackendInterface $bin): void {
if ($bin instanceof CacheTagsInvalidatorInterface) {
$this->bins[] = $bin;
}
return $bins;
}
}
......@@ -180,7 +180,7 @@ protected function processServiceCollectorPass(array $pass, $consumer_id, Contai
foreach ($this->tagCache[$tag] ?? [] as $id => $attributes) {
// Validate the interface.
$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.");
}
$handlers[$id] = $attributes[0]['priority'] ?? 0;
......
......@@ -279,14 +279,6 @@ parameters:
count: 1
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: """
#^Usage of deprecated trait Symfony\\\\Component\\\\DependencyInjection\\\\ContainerAwareTrait in class Drupal\\\\Core\\\\Cache\\\\ChainedFastBackendFactory\\:
......
......@@ -4,8 +4,9 @@
namespace Drupal\Tests\Core\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheTagsInvalidator;
use Drupal\Core\DependencyInjection\Container;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Tests\UnitTestCase;
/**
......@@ -26,47 +27,32 @@ public function testInvalidateTagsWithInvalidTags() {
/**
* @covers ::invalidateTags
* @covers ::addInvalidator
* @covers ::addBin
*/
public function testInvalidateTags() {
$cache_tags_invalidator = new CacheTagsInvalidator();
// This does not actually implement,
// \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 = $this->createMock(InvalidatingCacheBackendInterface::class);
$invalidator_cache_bin->expects($this->once())
->method('invalidateTags')
->with(['node:1']);
$cache_tags_invalidator->addBin($invalidator_cache_bin);
// 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
// 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_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 = $this->createMock(CacheTagsInvalidatorInterface::class);
$invalidator->expects($this->once())
->method('invalidateTags')
->with(['node:1']);
$cache_tags_invalidator->addInvalidator($invalidator);
$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