Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Cache] Fix versioned namespace atomic clears #35803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 24, 2020
Merged
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
Fix versioned namespace clears
When using namespace versioning to achieve atomic cache clears, only
delete cache keys matching the old/current version.

This resolves tag inconsistency issues whereby the process running the
clear would delete keys set against the new version by more recently
spawned concurreny processes. Most seriously this could result in newly
set data keys remaining, but with empty associated tag sets meaning the
invalidation via tags was no longer possible.

Clearing specific prefixes is not supported when using versioned
namespaces as it is desirable to clear all old keys as they will no
longer be used and would otherwise eventually fill cache memory.
  • Loading branch information
Trevor North committed Feb 20, 2020
commit 971b177d27ec43fca1ed6c027971190508bc5063
12 changes: 10 additions & 2 deletions 12 src/Symfony/Component/Cache/Traits/AbstractTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,14 @@ public function hasItem($key)
*/
public function clear(/*string $prefix = ''*/)
{
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
$this->deferred = [];
if ($cleared = $this->versioningIsEnabled) {
if ('' === $namespaceVersionToClear = $this->namespaceVersion) {
foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) {
$namespaceVersionToClear = $v;
}
}
$namespaceToClear = $this->namespace.$namespaceVersionToClear;
$namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5);
try {
$cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
Expand All @@ -124,10 +129,13 @@ public function clear(/*string $prefix = ''*/)
$this->namespaceVersion = $namespaceVersion;
$this->ids = [];
}
} else {
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
$namespaceToClear = $this->namespace.$prefix;
}

try {
return $this->doClear($this->namespace.$prefix) || $cleared;
return $this->doClear($namespaceToClear) || $cleared;
} catch (\Exception $e) {
CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);

Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.