From 9d81327d39639c37f90d71667fa4b0b1a8908710 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher <saschagros@gmail.com> Date: Wed, 12 Feb 2025 14:28:58 +0100 Subject: [PATCH] add a test and workaround --- src/Cache/CacheBase.php | 15 +++++++++++++- .../Kernel/ChainedFastWithRedisCacheTest.php | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Cache/CacheBase.php b/src/Cache/CacheBase.php index 696f4cb..e3f3e5f 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 8187323..06d05df 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)); + } + } -- GitLab