diff --git a/src/Cache/CacheBase.php b/src/Cache/CacheBase.php index 696f4cb6e88f0c3e3c2ef69c61dd63dc05225df2..e3f3e5fb817ee39307c9c25f49734460b14a4235 100644 --- a/src/Cache/CacheBase.php +++ b/src/Cache/CacheBase.php @@ -127,6 +127,16 @@ abstract class CacheBase implements CacheBackendInterface { $this->setPermTtl(); } + /** + * Returns the CID for the last write timestamp cache. + * + * @return string + * The last write timestamp CID. + */ + public function getLastWriteCid(): string { + return ChainedFastBackend::LAST_WRITE_TIMESTAMP_PREFIX . 'cache_' . $this->bin; + } + /** * Checks whether the cache id is the last write timestamp. * @@ -142,7 +152,7 @@ abstract class CacheBase implements CacheBackendInterface { * @return bool */ protected function isLastWriteTimestamp(string $cid): bool { - return $cid === ChainedFastBackend::LAST_WRITE_TIMESTAMP_PREFIX . 'cache_' . $this->bin; + return $cid === $this->getLastWriteCid(); } /** @@ -488,6 +498,9 @@ abstract class CacheBase implements CacheBackendInterface { usleep(1000); $this->lastDeleteAll = round(microtime(TRUE), 3); $this->client->set($this->getKey(static::LAST_DELETE_ALL_KEY), $this->lastDeleteAll); + + // Also delete the last write timestamp in case the bin is accessed directly. + $this->client->del($this->getPrefix() . ':' . $this->getLastWriteCid()); } } diff --git a/tests/src/Kernel/ChainedFastWithRedisCacheTest.php b/tests/src/Kernel/ChainedFastWithRedisCacheTest.php index 8187323839d2142f99007bd17caae4dc62d27a46..06d05dfcbc5426053a1c7936cd39158d655da384 100644 --- a/tests/src/Kernel/ChainedFastWithRedisCacheTest.php +++ b/tests/src/Kernel/ChainedFastWithRedisCacheTest.php @@ -30,4 +30,24 @@ class ChainedFastWithRedisCacheTest extends RedisCacheTest { return $backend; } + /** + * Tests calling deleteAll() on the consistent backend directly. + */ + public function testDeleteAllBypass() { + $backend = $this->getCacheBackend('example'); + + $cid = 'example_item'; + $backend->set($cid, 'foo'); + + // Explicitly create a new backend. + $backend = $this->createCacheBackend('example'); + $this->assertSame('foo', $backend->get($cid)->data); + + $consistent_backend = \Drupal::service('cache.backend.redis')->get('example'); + $consistent_backend->deleteAll(); + + $backend = $this->createCacheBackend('example'); + $this->assertFalse($backend->get($cid)); + } + }