Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9d760fb

Browse files
[Cache] serialize tags separately from values in AbstractTagAwareAdapter
1 parent c216f7f commit 9d760fb

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed

src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Psr\Log\LoggerAwareInterface;
1515
use Symfony\Component\Cache\CacheItem;
1616
use Symfony\Component\Cache\Exception\InvalidArgumentException;
17+
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
1718
use Symfony\Component\Cache\ResettableInterface;
1819
use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
1920
use Symfony\Component\Cache\Traits\ContractsTrait;
@@ -37,14 +38,17 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
3738

3839
private const TAGS_PREFIX = "\0tags\0";
3940

40-
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
41+
private $marshaller;
42+
43+
protected function __construct(string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
4144
{
45+
$this->marshaller = $marshaller;
4246
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
4347
if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
4448
throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, \strlen($namespace), $namespace));
4549
}
4650
$this->createCacheItem = \Closure::bind(
47-
static function ($key, $value, $isHit) use ($defaultLifetime) {
51+
static function ($key, $value, $isHit) use ($defaultLifetime, $marshaller) {
4852
$item = new CacheItem();
4953
$item->key = $key;
5054
$item->defaultLifetime = $defaultLifetime;
@@ -53,6 +57,10 @@ static function ($key, $value, $isHit) use ($defaultLifetime) {
5357
if (!\is_array($value) || !\array_key_exists('value', $value)) {
5458
return $item;
5559
}
60+
if ($marshaller && \is_string($value['tags'] ?? null)) {
61+
$value['value'] = $marshaller->unmarshall($value['value']);
62+
$value['tags'] = $marshaller->unmarshall($value['tags']);
63+
}
5664
$item->isHit = $isHit;
5765
// Extract value, tags and meta data from the cache value
5866
$item->value = $value['value'];
@@ -72,7 +80,7 @@ static function ($key, $value, $isHit) use ($defaultLifetime) {
7280
$getId = \Closure::fromCallable([$this, 'getId']);
7381
$tagPrefix = self::TAGS_PREFIX;
7482
$this->mergeByLifetime = \Closure::bind(
75-
static function ($deferred, &$expiredIds) use ($getId, $tagPrefix) {
83+
static function ($deferred, &$expiredIds) use ($getId, $tagPrefix, $marshaller) {
7684
$byLifetime = [];
7785
$now = microtime(true);
7886
$expiredIds = [];
@@ -93,6 +101,16 @@ static function ($deferred, &$expiredIds) use ($getId, $tagPrefix) {
93101
$value = ['value' => $item->value, 'tags' => []];
94102
}
95103

104+
$newTags = $value['tags'];
105+
106+
if ($marshaller) {
107+
$value = $marshaller->marshall($value, $failed);
108+
109+
if ($failed) {
110+
$value['fail'] = $item->value;
111+
}
112+
}
113+
96114
if ($metadata) {
97115
// For compactness, expiry and creation duration are packed, using magic numbers as separators
98116
$value['meta'] = pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME]);
@@ -101,10 +119,10 @@ static function ($deferred, &$expiredIds) use ($getId, $tagPrefix) {
101119
// Extract tag changes, these should be removed from values in doSave()
102120
$value['tag-operations'] = ['add' => [], 'remove' => []];
103121
$oldTags = $item->metadata[CacheItem::METADATA_TAGS] ?? [];
104-
foreach (array_diff($value['tags'], $oldTags) as $addedTag) {
122+
foreach (array_diff($newTags, $oldTags) as $addedTag) {
105123
$value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag);
106124
}
107-
foreach (array_diff($oldTags, $value['tags']) as $removedTag) {
125+
foreach (array_diff($oldTags, $newTags) as $removedTag) {
108126
$value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag);
109127
}
110128

@@ -149,6 +167,17 @@ abstract protected function doDelete(array $ids, array $tagData = []): bool;
149167
*/
150168
abstract protected function doInvalidate(array $tagIds): bool;
151169

170+
protected function doFetchTags(array $ids): iterable
171+
{
172+
foreach ($this->doFetch($ids) as $id => $value) {
173+
if ($this->marshaller && \is_string($value['tags'] ?? null)) {
174+
$value['tags'] = $this->marshaller->unmarshall($value['tags']);
175+
}
176+
177+
yield $id => $value['tags'] ?? [];
178+
}
179+
}
180+
152181
/**
153182
* {@inheritdoc}
154183
*
@@ -232,8 +261,8 @@ public function deleteItems(array $keys)
232261
unset($this->deferred[$key]);
233262
}
234263

235-
foreach ($this->doFetch($ids) as $id => $value) {
236-
foreach ($value['tags'] ?? [] as $tag) {
264+
foreach ($this->doFetchTags($ids) as $id => $tags) {
265+
foreach ($tags as $tag) {
237266
$tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id;
238267
}
239268
}

src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements Prune
3737

3838
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
3939
{
40-
$this->marshaller = $marshaller ?? new DefaultMarshaller();
41-
parent::__construct('', $defaultLifetime);
40+
$this->marshaller = new DefaultMarshaller();
41+
parent::__construct('', $defaultLifetime, $marshaller ?? new DefaultMarshaller());
4242
$this->init($namespace, $directory);
4343
}
4444

src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Predis\Connection\Aggregate\PredisCluster;
1616
use Predis\Response\Status;
1717
use Symfony\Component\Cache\Exception\InvalidArgumentException;
18+
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
1819
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
1920
use Symfony\Component\Cache\Traits\RedisTrait;
2021

@@ -67,7 +68,9 @@ public function __construct($redisClient, string $namespace = '', int $defaultLi
6768
throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, \get_class($redisClient->getConnection())));
6869
}
6970

70-
$this->init($redisClient, $namespace, $defaultLifetime, $marshaller);
71+
parent::__construct($namespace, $defaultLifetime, $marshaller ?? new DefaultMarshaller());
72+
73+
$this->init($redisClient, $namespace, $defaultLifetime, new DefaultMarshaller(), false);
7174
}
7275

7376
/**

src/Symfony/Component/Cache/Traits/AbstractAdapterTrait.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ public function getItem($key)
5151
foreach ($this->doFetch([$id]) as $value) {
5252
$isHit = true;
5353
}
54+
55+
return $f($key, $value, $isHit);
5456
} catch (\Exception $e) {
5557
CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
5658
}
5759

58-
return $f($key, $value, $isHit);
60+
return $f($key, null, false);
5961
}
6062

6163
/**

src/Symfony/Component/Cache/Traits/RedisTrait.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ trait RedisTrait
4848
/**
4949
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface $redisClient
5050
*/
51-
private function init($redisClient, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller)
51+
private function init($redisClient, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller, bool $callConstructor = true)
5252
{
53-
parent::__construct($namespace, $defaultLifetime);
53+
if ($callConstructor) {
54+
parent::__construct($namespace, $defaultLifetime);
55+
}
5456

5557
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
5658
throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));

0 commit comments

Comments
 (0)