Skip to content

Commit

Permalink
Add full phpredis support to the cache component
Browse files Browse the repository at this point in the history
- Improved the RedisStore to support phpredis serialization and compression settings.
- Improve test suite related to phpredis.
  • Loading branch information
TheLevti committed Jan 24, 2022
1 parent 4bffc87 commit 1969e67
Show file tree
Hide file tree
Showing 22 changed files with 1,541 additions and 1,397 deletions.
16 changes: 16 additions & 0 deletions src/Illuminate/Cache/LuaScripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ public static function releaseLock()
else
return 0
end
LUA;
}

/**
* Get the Lua script that sets a key only when it does not yet exist.
*
* KEYS[1] - The name of the key
* ARGV[1] - Value of the key
* ARGV[2] - Time in seconds how long to keep the key
*
* @return string
*/
public static function add()
{
return <<<'LUA'
return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])
LUA;
}
}
82 changes: 72 additions & 10 deletions src/Illuminate/Cache/RedisStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ public function __construct(Redis $redis, $prefix = '', $connection = 'default')
*/
public function get($key)
{
$value = $this->connection()->get($this->prefix.$key);
$connection = $this->connection();

return ! is_null($value) ? $this->unserialize($value) : null;
$value = $connection->get($this->prefix.$key);

return $value === null ? null : $this->connectionAwareUnserialize($value, $connection);
}

/**
Expand All @@ -76,12 +78,14 @@ public function many(array $keys)
{
$results = [];

$values = $this->connection()->mget(array_map(function ($key) {
$connection = $this->connection();

$values = $connection->mget(array_map(function ($key) {
return $this->prefix.$key;
}, $keys));

foreach ($values as $index => $value) {
$results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
$results[$keys[$index]] = $value === null ? null : $this->connectionAwareUnserialize($value, $connection);
}

return $results;
Expand All @@ -97,8 +101,10 @@ public function many(array $keys)
*/
public function put($key, $value, $seconds)
{
return (bool) $this->connection()->setex(
$this->prefix.$key, (int) max(1, $seconds), $this->serialize($value)
$connection = $this->connection();

return (bool) $connection->setex(
$this->prefix.$key, (int) max(1, $seconds), $this->connectionAwareSerialize($value, $connection)
);
}

Expand Down Expand Up @@ -136,10 +142,10 @@ public function putMany(array $values, $seconds)
*/
public function add($key, $value, $seconds)
{
$lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
$connection = $this->connection();

return (bool) $this->connection()->eval(
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $seconds)
return (bool) $connection->eval(
LuaScripts::add(), 1, $this->prefix.$key, $this->pack($value, $connection), (int) max(1, $seconds)
);
}

Expand Down Expand Up @@ -176,7 +182,9 @@ public function decrement($key, $value = 1)
*/
public function forever($key, $value)
{
return (bool) $this->connection()->set($this->prefix.$key, $this->serialize($value));
$connection = $this->connection();

return (bool) $connection->set($this->prefix.$key, $this->connectionAwareSerialize($value, $connection));
}

/**
Expand Down Expand Up @@ -344,4 +352,58 @@ protected function unserialize($value)
{
return is_numeric($value) ? $value : unserialize($value);
}

/**
* Prepares a value to be used with the redis cache store when used with eval scripts.
*
* @param mixed $value
* @param \Illuminate\Redis\Connections\Connection $connection
* @return mixed
*/
protected function pack($value, $connection)
{
if ($connection instanceof PhpRedisConnection) {
if ($connection->serialized()) {
return $connection->pack([$value])[0];
}

if ($connection->compressed()) {
return $connection->pack([$this->serialize($value)])[0];
}
}

return $this->serialize($value);
}

/**
* Does connection specific considerations when a value needs to be serialized.
*
* @param mixed $value
* @param \Illuminate\Redis\Connections\Connection $connection
* @return mixed
*/
protected function connectionAwareSerialize($value, $connection)
{
if ($connection instanceof PhpRedisConnection && $connection->serialized()) {
return $value;
}

return $this->serialize($value);
}

/**
* Does connection specific considerations when a value needs to be unserialized.
*
* @param mixed $value
* @param \Illuminate\Redis\Connections\Connection $connection
* @return mixed
*/
protected function connectionAwareUnserialize($value, $connection)
{
if ($connection instanceof PhpRedisConnection && $connection->serialized()) {
return $value;
}

return $this->unserialize($value);
}
}
Loading

0 comments on commit 1969e67

Please sign in to comment.