diff --git a/core/core.services.yml b/core/core.services.yml index 65e0a40..2ae1da0 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -33,16 +33,17 @@ services: tags: - { name: cache.context} cache_tags.invalidator: + parent: container.trait class: Drupal\Core\Cache\CacheTagsInvalidator calls: - [setContainer, ['@service_container']] tags: - - { name: service_collector, call: addInvalidator } - cache_tags.checksum: + - { name: service_collector, call: addInvalidator, tag: cache_tags_invalidator } + cache_tags.invalidator.checksum: class: Drupal\Core\Cache\DatabaseCacheTagsChecksum arguments: ['@database'] tags: - - { name: cache_tags.invalidator} + - { name: cache_tags_invalidator} cache.backend.chainedfast: class: Drupal\Core\Cache\ChainedFastBackendFactory arguments: ['@settings'] @@ -50,13 +51,13 @@ services: - [setContainer, ['@service_container']] cache.backend.database: class: Drupal\Core\Cache\DatabaseBackendFactory - arguments: ['@database', '@cache_tags.checksum'] + arguments: ['@database', '@cache_tags.invalidator.checksum'] cache.backend.apcu: class: Drupal\Core\Cache\ApcuBackendFactory - arguments: ['@app.root', '@cache_tags.checksum'] + arguments: ['@app.root', '@cache_tags.invalidator.checksum'] cache.backend.php: class: Drupal\Core\Cache\PhpBackendFactory - arguments: ['@cache_tags.checksum'] + arguments: ['@cache_tags.invalidator.checksum'] cache.bootstrap: class: Drupal\Core\Cache\CacheBackendInterface tags: diff --git a/core/lib/Drupal/Core/Cache/ApcuBackend.php b/core/lib/Drupal/Core/Cache/ApcuBackend.php index e406d0f..46a73b6 100644 --- a/core/lib/Drupal/Core/Cache/ApcuBackend.php +++ b/core/lib/Drupal/Core/Cache/ApcuBackend.php @@ -10,7 +10,7 @@ /** * Stores cache items in the Alternative PHP Cache User Cache (APCu). */ -class ApcuBackend implements CacheBackendInterface, CacheTagsInvalidatorInterface { +class ApcuBackend implements CacheBackendInterface { /** * The name of the cache bin to use. @@ -183,11 +183,8 @@ protected function prepareItem($cache, $allow_invalid) { * {@inheritdoc} */ public function set($cid, $data, $expire = CacheBackendInterface::CACHE_PERMANENT, array $tags = array()) { - if ($tags) { - $tags = array_unique($tags); - Cache::validateTags($tags); - } - + Cache::validateTags($tags); + $tags = array_unique($tags); $cache = new \stdClass(); $cache->cid = $cid; $cache->created = round(microtime(TRUE), 3); @@ -278,16 +275,4 @@ public function invalidateAll() { } } - /** - * {@inheritdoc} - */ - public function invalidateTags(array $tags) { - foreach ($tags as $tag) { - apc_inc($this->invalidationsTagsPrefix . $tag, 1, $success); - if (!$success) { - apc_store($this->invalidationsTagsPrefix . $tag, 1); - } - } - } - } diff --git a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php index e5aa85d..faf2459 100644 --- a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php +++ b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php @@ -178,7 +178,6 @@ public function deleteAll(); * * @see \Drupal\Core\Cache\CacheBackendInterface::delete() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple() - * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateTags() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateAll() */ public function invalidate($cid); @@ -189,12 +188,11 @@ public function invalidate($cid); * Invalid items may be returned in later calls to get(), if the $allow_invalid * argument is TRUE. * - * @param string $cids + * @param string[] $cids * An array of cache IDs to invalidate. * * @see \Drupal\Core\Cache\CacheBackendInterface::deleteMultiple() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidate() - * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateTags() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateAll() */ public function invalidateMultiple(array $cids); @@ -205,13 +203,9 @@ public function invalidateMultiple(array $cids); * Invalid items may be returned in later calls to get(), if the $allow_invalid * argument is TRUE. * - * @param string $cids - * An array of cache IDs to invalidate. - * * @see \Drupal\Core\Cache\CacheBackendInterface::deleteAll() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidate() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple() - * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateTags() */ public function invalidateAll(); diff --git a/core/lib/Drupal/Core/Cache/CacheTagsChecksumInterface.php b/core/lib/Drupal/Core/Cache/CacheTagsChecksumInterface.php index 265f624..a140112 100644 --- a/core/lib/Drupal/Core/Cache/CacheTagsChecksumInterface.php +++ b/core/lib/Drupal/Core/Cache/CacheTagsChecksumInterface.php @@ -10,7 +10,14 @@ /** * Provides checksums for cache tag invalidations. * - * Cache backends can use this to check if any cache tag invalidations + * Cache backends can use this to check if any cache tag invalidations happened + * for a stored cache item. + * + * To do so, they can inject the cache_tags.invalidator.checksum service, and + * when a cache item is written, store cache tags together with the current + * checksum, calculated by getCurrentChecksum(). When a cache item is fetched, + * the checksum can be validated with isValid(). The service will return FALSE + * if any of those cache tags were invalidated in the meantime. * * @ingroup cache */ diff --git a/core/lib/Drupal/Core/Cache/CacheTagsInvalidatorInterface.php b/core/lib/Drupal/Core/Cache/CacheTagsInvalidatorInterface.php index 4db0a96..bf63041 100644 --- a/core/lib/Drupal/Core/Cache/CacheTagsInvalidatorInterface.php +++ b/core/lib/Drupal/Core/Cache/CacheTagsInvalidatorInterface.php @@ -10,6 +10,10 @@ /** * Defines required methods for classes wanting to handle cache tag changes. * + * Services that implement this interface must add the cache_tags_invalidator + * tag to be notified. Cache backends may implement this interface as well, they + * will be notified automatically. + * * @ingroup cache */ interface CacheTagsInvalidatorInterface { diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index 044c910..4610636 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -150,12 +150,10 @@ protected function prepareItem($cache, $allow_invalid) { * Implements Drupal\Core\Cache\CacheBackendInterface::set(). */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { - if ($tags) { - Cache::validateTags($tags); - $tags = array_unique($tags); - // Sort the cache tags so that they are stored consistently in the database. - sort($tags); - } + Cache::validateTags($tags); + $tags = array_unique($tags); + // Sort the cache tags so that they are stored consistently in the database. + sort($tags); $try_again = FALSE; try { // The bin might not yet exist. @@ -223,12 +221,10 @@ public function setMultiple(array $items) { 'tags' => array(), ); - if ($item['tags']) { - Cache::validateTags($item['tags']); - $item['tags'] = array_unique($item['tags']); - // Sort the cache tags so that they are stored consistently in the DB. - sort($item['tags']); - } + Cache::validateTags($item['tags']); + $item['tags'] = array_unique($item['tags']); + // Sort the cache tags so that they are stored consistently in the DB. + sort($item['tags']); $fields = array( 'cid' => $cid, diff --git a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php index 784294e..4375b45 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php +++ b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php @@ -82,7 +82,9 @@ public function invalidateTags(array $tags) { */ public function getCurrentChecksum(array $tags) { // Remove tags that were already invalidated during this request from the - // static caches so that another deletion or invalidation can occur. + // static caches so that another invalidation can occur later in the same + // request. Without that, written cache items would not be invalidated + // correctly. foreach ($tags as $tag) { unset($this->invalidatedTags[$tag]); } diff --git a/core/lib/Drupal/Core/Cache/PhpBackend.php b/core/lib/Drupal/Core/Cache/PhpBackend.php index df6ffa7..b665e86 100644 --- a/core/lib/Drupal/Core/Cache/PhpBackend.php +++ b/core/lib/Drupal/Core/Cache/PhpBackend.php @@ -148,16 +148,13 @@ protected function prepareItem($cache, $allow_invalid) { * {@inheritdoc} */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { - if ($tags) { - $tags = array_unique($tags); - Cache::validateTags($tags); - } + Cache::validateTags($tags); $item = (object) array( 'cid' => $cid, 'data' => $data, 'created' => round(microtime(TRUE), 3), 'expire' => $expire, - 'tags' => $tags, + 'tags' => array_unique($tags), 'checksum' => $this->checksumProvider->getCurrentChecksum($tags), ); $this->writeItem($this->normalizeCid($cid), $item); @@ -218,18 +215,6 @@ public function invalidateMultiple(array $cids) { /** * {@inheritdoc} */ - public function invalidateTags(array $tags) { - foreach ($this->storage()->listAll() as $cidhash) { - $item = $this->getByHash($cidhash); - if ($item && array_intersect($tags, $item->tags)) { - $this->invalidate($item->cid); - } - } - } - - /** - * {@inheritdoc} - */ public function invalidateAll() { foreach($this->storage()->listAll() as $cidhash) { $this->invalidatebyHash($cidhash); diff --git a/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php index d18a8c7..9b0eb65 100644 --- a/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php +++ b/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php @@ -8,7 +8,6 @@ namespace Drupal\Core\Field; use Drupal\Core\Entity\FieldableEntityInterface; -use Drupal\Core\TypedData\DataDefinitionInterface; /** * Defines an interface for entity field storage definitions. diff --git a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php index 15a7e79..9862552 100644 --- a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php +++ b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php @@ -52,7 +52,7 @@ public function register(ContainerBuilder $container) { // Remove the cache tags invalidator tag from the cache tags storage, so // that we don't call it when cache tags are invalidated very early in the // installer. - $container->getDefinition('cache_tags.checksum') + $container->getDefinition('cache_tags.invalidator.checksum') ->clearTag('cache_tags.invalidator'); // Replace the route builder with an empty implementation. diff --git a/core/modules/config/src/Tests/Storage/CachedStorageTest.php b/core/modules/config/src/Tests/Storage/CachedStorageTest.php index f7dd32e..66f6225 100644 --- a/core/modules/config/src/Tests/Storage/CachedStorageTest.php +++ b/core/modules/config/src/Tests/Storage/CachedStorageTest.php @@ -91,7 +91,7 @@ public function containerBuild(ContainerBuilder $container) { // Use the regular database cache backend to aid testing. $container->register('cache_factory', 'Drupal\Core\Cache\DatabaseBackendFactory') ->addArgument(new Reference('database')) - ->addArgument(new Reference('cache_tags.checksum')); + ->addArgument(new Reference('cache_tags.invalidator.checksum')); } } diff --git a/core/modules/locale/src/Tests/LocaleTranslationUiTest.php b/core/modules/locale/src/Tests/LocaleTranslationUiTest.php index f918e1e..55d48e7 100644 --- a/core/modules/locale/src/Tests/LocaleTranslationUiTest.php +++ b/core/modules/locale/src/Tests/LocaleTranslationUiTest.php @@ -137,7 +137,7 @@ public function testStringTranslation() { // Reset the tag cache on the tester side in order to pick up the call to // Cache::invalidateTags() on the tested side. - \Drupal::service('cache_tags.checksum')->reset(); + \Drupal::service('cache_tags.invalidator.checksum')->reset(); $this->assertTrue($name != $translation && t($name, array(), array('langcode' => $langcode)) == $translation, 't() works for non-English.'); // Refresh the locale() cache to get fresh data from t() below. We are in diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 51e5940..4c993b2 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -1151,7 +1151,7 @@ protected function resetAll() { */ protected function refreshVariables() { // Clear the tag cache. - \Drupal::service('cache_tags.checksum')->reset(); + \Drupal::service('cache_tags.invalidator.checksum')->reset(); foreach (Cache::getBins() as $backend) { if (is_callable(array($backend, 'reset'))) { $backend->reset(); diff --git a/core/modules/system/src/Tests/Cache/ApcuBackendUnitTest.php b/core/modules/system/src/Tests/Cache/ApcuBackendUnitTest.php index 14bb16c..20fb3a4 100644 --- a/core/modules/system/src/Tests/Cache/ApcuBackendUnitTest.php +++ b/core/modules/system/src/Tests/Cache/ApcuBackendUnitTest.php @@ -34,8 +34,7 @@ protected function checkRequirements() { } protected function createCacheBackend($bin) { - $backend = new ApcuBackend($bin, $this->databasePrefix, \Drupal::service('cache_tags.checksum')); - return $backend; + return new ApcuBackend($bin, $this->databasePrefix, \Drupal::service('cache_tags.invalidator.checksum')); } protected function tearDown() { diff --git a/core/modules/system/src/Tests/Cache/ChainedFastBackendUnitTest.php b/core/modules/system/src/Tests/Cache/ChainedFastBackendUnitTest.php index 961c10a..c34563c 100644 --- a/core/modules/system/src/Tests/Cache/ChainedFastBackendUnitTest.php +++ b/core/modules/system/src/Tests/Cache/ChainedFastBackendUnitTest.php @@ -25,8 +25,8 @@ class ChainedFastBackendUnitTest extends GenericCacheBackendUnitTestBase { * A new ChainedFastBackend object. */ protected function createCacheBackend($bin) { - $consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.checksum'), $bin); - $fast_backend = new PhpBackend($bin, \Drupal::service('cache_tags.checksum')); + $consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin); + $fast_backend = new PhpBackend($bin, \Drupal::service('cache_tags.invalidator.checksum')); $backend = new ChainedFastBackend($consistent_backend, $fast_backend, $bin); // Explicitly register the cache bin as it can not work through the // cache bin list in the container. diff --git a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php index 91009f8..e54198b 100644 --- a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php +++ b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php @@ -30,7 +30,7 @@ class DatabaseBackendUnitTest extends GenericCacheBackendUnitTestBase { * A new DatabaseBackend object. */ protected function createCacheBackend($bin) { - return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.checksum'), $bin); + return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin); } } diff --git a/core/modules/system/src/Tests/Cache/PhpBackendUnitTest.php b/core/modules/system/src/Tests/Cache/PhpBackendUnitTest.php index 507c16f..1751883 100644 --- a/core/modules/system/src/Tests/Cache/PhpBackendUnitTest.php +++ b/core/modules/system/src/Tests/Cache/PhpBackendUnitTest.php @@ -23,7 +23,7 @@ class PhpBackendUnitTest extends GenericCacheBackendUnitTestBase { * A new MemoryBackend object. */ protected function createCacheBackend($bin) { - $backend = new PhpBackend($bin, \Drupal::service('cache_tags.checksum')); + $backend = new PhpBackend($bin, \Drupal::service('cache_tags.invalidator.checksum')); return $backend; } diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheTagsInvalidatorTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheTagsInvalidatorTest.php index adfb7a3..1424b1e 100644 --- a/core/tests/Drupal/Tests/Core/Cache/CacheTagsInvalidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/CacheTagsInvalidatorTest.php @@ -17,7 +17,6 @@ */ class CacheTagsInvalidatorTest extends UnitTestCase { - /** * @covers ::invalidateTags * @@ -48,7 +47,7 @@ public function testInvalidateTags() { // 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->getMock('\Drupal\Core\Cache\CacheBackendI'); + $non_invalidator_cache_bin = $this->getMock('\Drupal\Core\Cache\CacheBackendInterface'); $container = new Container(); $container->set('cache.invalidator_cache_bin', $invalidator_cache_bin);