Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Add phpredis serialization and compression support to the cache component #40569

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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