diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php index edf9a80aad497..2602f0070490d 100644 --- a/lib/private/Memcache/Redis.php +++ b/lib/private/Memcache/Redis.php @@ -39,6 +39,8 @@ class Redis extends Cache implements IMemcacheTTL { private const MAX_TTL = 30 * 24 * 60 * 60; // 1 month + private const NO_SCRIPT_ERROR_MESSAGE_PREFIX = 'NOSCRIPT'; + private \Redis|\RedisCluster|null $cache = null; public function __construct($prefix = '', string $logFile = '') { @@ -218,12 +220,29 @@ protected function evalLua(string $scriptName, array $keys, array $args) { $args = array_merge($keys, $args); $script = self::LUA_SCRIPTS[$scriptName]; - $result = $this->getCache()->evalSha($script[1], $args, count($keys)); - if ($result === false) { - $result = $this->getCache()->eval($script[0], $args, count($keys)); + $cache = $this->getCache(); + $cache->clearLastError(); + + $result = $cache->evalSha($script[1], $args, count($keys)); + if ($result !== false) { + return $result; + } + + $error = $cache->getLastError(); + if ($error !== null && str_starts_with($error, self::NO_SCRIPT_ERROR_MESSAGE_PREFIX)) { + $cache->clearLastError(); + return $cache->eval($script[0], $args, count($keys)); + } + + if ($error !== null && str_starts_with($error, 'WRONGTYPE')) { + return false; + } + + if ($error !== null) { + throw new \RuntimeException('Redis EVALSHA failed: ' . $error); } - return $result; + return false; } protected static function encodeValue(mixed $value): string {