10000 bug #45339 [Cache] fix error handling when using Redis (nicolas-grekas) · symfony/symfony@8f7420c · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f7420c

Browse files
bug #45339 [Cache] fix error handling when using Redis (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [Cache] fix error handling when using Redis | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #45325 | License | MIT | Doc PR | - Spotted while working on #45313 I won't be able to add tests here, the situations are too edgy. Commits ------- 3c59e0f [Cache] fix error handling
2 parents f80754f + 3c59e0f commit 8f7420c

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,12 @@ public function commit()
157157
$retry = $this->deferred = [];
158158

159159
if ($expiredIds) {
160-
$this->doDelete($expiredIds);
160+
try {
161+
$this->doDelete($expiredIds);
162+
} catch (\Exception $e) {
163+
$ok = false;
164+
CacheItem::log($this->logger, 'Failed to delete expired items: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);
165+
}
161166
}
162167
foreach ($byLifetime as $lifetime => $values) {
163168
try {

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,12 @@ public function commit(): bool
181181

182182
if ($expiredIds) {
183183
// Tags are not cleaned up in this case, however that is done on invalidateTags().
184-
$this->doDelete($expiredIds);
184+
try {
185+
$this->doDelete($expiredIds);
186+
} catch (\Exception $e) {
187+
$ok = false;
188+
CacheItem::log($this->logger, 'Failed to delete expired items: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);
189+
}
185190
}
186191
foreach ($byLifetime as $lifetime => $values) {
187192
try {
@@ -295,8 +300,12 @@ public function invalidateTags(array $tags)
295300
$tagIds[] = $this->getId(self::TAGS_PREFIX.$tag);
296301
}
297302

298-
if ($this->doInvalidate($tagIds)) {
299-
return true;
303+
try {
304+
if ($this->doInvalidate($tagIds)) {
305+
return true;
306+
}
307+
} catch (\Exception $e) {
308+
CacheItem::log($this->logger, 'Failed to invalidate tags: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);
300309
}
301310

302311
return false;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Predis\Connection\Aggregate\ClusterInterface;
1515
use Predis\Connection\Aggregate\PredisCluster;
1616
use Predis\Connection\Aggregate\ReplicationInterface;
17+
use Predis\Response\ErrorInterface;
1718
use Predis\Response\Status;
1819
use Symfony\Component\Cache\CacheItem;
1920
use Symfony\Component\Cache\Exception\InvalidArgumentException;
@@ -58,6 +59,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
5859
* @var string|null detected eviction policy used on Redis server
5960
*/
6061
private $redisEvictionPolicy;
62+
private $namespace;
6163

6264
/**
6365
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis The redis client
@@ -81,6 +83,7 @@ public function __construct($redis, string $namespace = '', int $defaultLifetime
8183
}
8284

8385
$this->init($redis, $namespace, $defaultLifetime, new TagAwareMarshaller($marshaller));
86+
$this->namespace = $namespace;
8487
}
8588

8689
/**
@@ -160,7 +163,7 @@ protected function doDeleteYieldTags(array $ids): iterable
160163
});
161164

162165
foreach ($results as $id => $result) {
163-
if ($result instanceof \RedisException) {
166+
if ($result instanceof \RedisException || $result instanceof ErrorInterface) {
164167
CacheItem::log($this->logger, 'Failed to delete key "{key}": '.$result->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $result]);
165168

166169
continue;
@@ -254,7 +257,7 @@ protected function doInvalidate(array $tagIds): bool
254257

255258
$success = true;
256259
foreach ($results as $id => $values) {
257-
if ($values instanceof \RedisException) {
260+
if ($values instanceof \RedisException || $values instanceof ErrorInterface) {
258261
CacheItem::log($this->logger, 'Failed to invalidate key "{key}": '.$values->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $values]);
259262
$success = false;
260263

@@ -303,6 +306,11 @@ private function getRedisEvictionPolicy(): string
303306

304307
foreach ($hosts as $host) {
305308
$info = $host->info('Memory');
309+
310+
if ($info instanceof ErrorInterface) {
311+
continue;
312+
}
313+
306314
$info = $info['Memory'] ?? $info;
307315

308316
return $this->redisEvictionPolicy = $info['maxmemory_policy'];

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Predis\Connection\Aggregate\ClusterInterface;
1515
use Predis\Connection\Aggregate\RedisCluster;
1616
use Predis\Connection\Aggregate\ReplicationInterface;
17+
use Predis\Response\ErrorInterface;
1718
use Predis\Response\Status;
1819
use Symfony\Component\Cache\Exception\CacheException;
1920
use Symfony\Component\Cache\Exception\InvalidArgumentException;
@@ -386,7 +387,7 @@ protected function doClear($namespace)
386387
}
387388

388389
$info = $host->info('Server');
389-
$info = $info['Server'] ?? $info;
390+
$info = !$info instanceof ErrorInterface ? $info['Server'] ?? $info : ['redis_version' => '2.0'];
390391

391392
if (!$host instanceof \Predis\ClientInterface) {
392393
$prefix = \defined('Redis::SCAN_PREFIX') && (\Redis::SCAN_PREFIX & $host->getOption(\Redis::OPT_SCAN)) ? '' : $host->getOption(\Redis::OPT_PREFIX);

0 commit comments

Comments
 (0)
0