Skip to content

Commit

Permalink
bug #54252 [Lock] compatiblity with redis cluster 7 (bastnic)
Browse files Browse the repository at this point in the history
This PR was merged into the 5.4 branch.

Discussion
----------

[Lock] compatiblity with redis cluster 7

| Q             | A |
| ------------- | --- |
| Branch?       | 5.4 |
| Bug fix?      | yes |
| New feature?  | no |
| Deprecations? | no |
| License       | MIT |

While upgrading from redis 5 (no cluster) to AWS Elasticache redis 7 (cluster serverless), I stumble upon a fail.

```
This Redis command is not allowed from script script
```

Investigating, the fail is here, `TIME` is not available in cluster mode.

https://github.com/symfony/symfony/blob/d508d5f3a91b446452ee92a3e04fd66b44afe88a/src/Symfony/Component/Lock/Store/RedisStore.php#L272-L281

```
redis > EVAL 'local now = redis.call("TIME"); redis.call("SET", KEYS[1], "1", "PX", 1); return 1;' 1 pouet
(error) ERR This Redis command is not allowed from script script: b0e701c57bb0187cbd6ec8e404a7f6ba19b11a94, on `@user_script`:1.
```

BUT the error does not contains `commands not allowed after non deterministic` anymore, so no fallback on the PHP implementation.

Hence, the new exception catch.

See https://redis.io/docs/interact/programmability/eval-intro/#replicating-commands-instead-of-scripts

Commits
-------

ee5bd73 [Lock] compatiblity with redis cluster 7
  • Loading branch information
nicolas-grekas committed Mar 13, 2024
2 parents 7dde058 + ee5bd73 commit c44cc73
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/Symfony/Component/Lock/Store/RedisStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ public function exists(Key $key)
private function evaluate(string $script, string $resource, array $args)
{
if (
$this->redis instanceof \Redis ||
$this->redis instanceof \RedisCluster ||
$this->redis instanceof RedisProxy ||
$this->redis instanceof RedisClusterProxy
$this->redis instanceof \Redis
|| $this->redis instanceof \RedisCluster
|| $this->redis instanceof RedisProxy
|| $this->redis instanceof RedisClusterProxy
) {
$this->redis->clearLastError();
$result = $this->redis->eval($script, array_merge([$resource], $args), 1);
Expand Down Expand Up @@ -317,7 +317,9 @@ private function getNowCode(): string
try {
$this->supportTime = 1 === $this->evaluate($script, 'symfony_check_support_time', []);
} catch (LockStorageException $e) {
if (false === strpos($e->getMessage(), 'commands not allowed after non deterministic')) {
if (!str_contains($e->getMessage(), 'commands not allowed after non deterministic')
&& !str_contains($e->getMessage(), 'is not allowed from script script')
) {
throw $e;
}
$this->supportTime = false;
Expand Down

0 comments on commit c44cc73

Please sign in to comment.