Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ jobs:
composer update ${{ matrix.dependencies == 'lowest' && '--prefer-lowest' || '' }} ${{ env.COMPOSER_FLAGS }} ${{ matrix.php-version == '8.5' && '--ignore-platform-req=ext-redis --ignore-platform-req=ext-memcached' || '' }}

- name: Run PHPUnit tests
run: ./vendor/bin/phpunit --coverage-clover=coverage.xml
run: ./vendor/bin/phpunit ${{ (matrix.os == 'ubuntu-latest' && matrix.php-version == '8.4' && matrix.dependencies == 'highest') && '--coverage-clover=coverage.xml' || '' }}

- name: Upload coverage report
if: matrix.os == 'ubuntu-latest' && matrix.php-version == '8.4' && matrix.dependencies == 'highest'
Expand Down
8 changes: 6 additions & 2 deletions src/ResourceStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,12 @@ public function saveDonutView(ResourceObject $ro, int|null $ttl): bool
/** @return list<string> */
private function getTags(ResourceObject $ro): array
{
$etag = $ro->headers['ETag'];
$tags = [$etag, ($this->uriTag)($ro->uri)];
// ETag is intentionally NOT used as an invalidation tag. The cache entry is
// purged by its URI tag (deleteEtag/invalidateTags) and surrogate keys; no code
// path ever invalidates by ETag. Because ETag is content-versioned, registering it
// as a tag produced one non-volatile tag Set per content version that, under a
// volatile-* eviction policy, is never reclaimed - leaking memory without being read.
$tags = [($this->uriTag)($ro->uri)];
if (isset($ro->headers[Header::SURROGATE_KEY])) {
$tags = array_merge($tags, explode(' ', $ro->headers[Header::SURROGATE_KEY]));
}
Expand Down
14 changes: 14 additions & 0 deletions tests/ResourceStorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,18 @@ public function testSaveGetStatic(): void
$donut = $this->storage->getDonut($this->ro->uri);
$this->assertInstanceOf(ResourceDonut::class, $donut);
}

public function testEtagIsNotRegisteredAsInvalidationTag(): void
{
$this->ro->headers['ETag'] = 'test-etag-value';
$this->storage->saveValue($this->ro, 0);

// ETag is not an invalidation tag: invalidating by the ETag value must NOT purge the entry.
$this->storage->invalidateTags(['test-etag-value']);
$this->assertNotNull($this->storage->get($this->ro->uri));

// The URI tag still invalidates the same entry.
$this->storage->invalidateTags([(new UriTag())($this->ro->uri)]);
$this->assertNull($this->storage->get($this->ro->uri));
}
}
Loading