bug #35803 [Cache] Fix versioned namespace atomic clears (trvrnrth)
This PR was merged into the 4.4 branch.
Discussion
----------
[Cache] Fix versioned namespace atomic clears
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| License | MIT
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 concurrent 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.
Commits
-------
971b177d27
Fix versioned namespace clears
This commit is contained in:
commit
c0caef1708
|
@ -111,9 +111,14 @@ trait AbstractTrait
|
||||||
*/
|
*/
|
||||||
public function clear(/*string $prefix = ''*/)
|
public function clear(/*string $prefix = ''*/)
|
||||||
{
|
{
|
||||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
|
||||||
$this->deferred = [];
|
$this->deferred = [];
|
||||||
if ($cleared = $this->versioningIsEnabled) {
|
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);
|
$namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5);
|
||||||
try {
|
try {
|
||||||
$cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
|
$cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
|
||||||
|
@ -124,10 +129,13 @@ trait AbstractTrait
|
||||||
$this->namespaceVersion = $namespaceVersion;
|
$this->namespaceVersion = $namespaceVersion;
|
||||||
$this->ids = [];
|
$this->ids = [];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||||
|
$namespaceToClear = $this->namespace.$prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $this->doClear($this->namespace.$prefix) || $cleared;
|
return $this->doClear($namespaceToClear) || $cleared;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
|
CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
|
||||||
|
|
||||||
|
|
Reference in New Issue