MDL-69121 core: Add ZSTD/Gzip compression options to Redis sessions
This commit is contained in:
@@ -40,6 +40,19 @@ defined('MOODLE_INTERNAL') || die();
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class redis extends handler {
|
||||
/**
|
||||
* Compressor: none.
|
||||
*/
|
||||
const COMPRESSION_NONE = 'none';
|
||||
/**
|
||||
* Compressor: PHP GZip.
|
||||
*/
|
||||
const COMPRESSION_GZIP = 'gzip';
|
||||
/**
|
||||
* Compressor: PHP Zstandard.
|
||||
*/
|
||||
const COMPRESSION_ZSTD = 'zstd';
|
||||
|
||||
/** @var string $host save_path string */
|
||||
protected $host = '';
|
||||
/** @var int $port The port to connect to */
|
||||
@@ -56,6 +69,8 @@ class redis extends handler {
|
||||
protected $lockretry = 100;
|
||||
/** @var int $serializer The serializer to use */
|
||||
protected $serializer = \Redis::SERIALIZER_PHP;
|
||||
/** @var int $compressor The compressor to use */
|
||||
protected $compressor = self::COMPRESSION_NONE;
|
||||
/** @var string $lasthash hash of the session data content */
|
||||
protected $lasthash = null;
|
||||
|
||||
@@ -122,6 +137,10 @@ class redis extends handler {
|
||||
if (isset($CFG->session_redis_lock_expire)) {
|
||||
$this->lockexpire = (int)$CFG->session_redis_lock_expire;
|
||||
}
|
||||
|
||||
if (isset($CFG->session_redis_compressor)) {
|
||||
$this->compressor = $CFG->session_redis_compressor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,7 +287,8 @@ class redis extends handler {
|
||||
if ($this->requires_write_lock()) {
|
||||
$this->lock_session($id);
|
||||
}
|
||||
$sessiondata = $this->connection->get($id);
|
||||
$sessiondata = $this->uncompress($this->connection->get($id));
|
||||
|
||||
if ($sessiondata === false) {
|
||||
if ($this->requires_write_lock()) {
|
||||
$this->unlock_session($id);
|
||||
@@ -285,6 +305,53 @@ class redis extends handler {
|
||||
return $sessiondata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses session data.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
private function compress($value) {
|
||||
switch ($this->compressor) {
|
||||
case self::COMPRESSION_NONE:
|
||||
return $value;
|
||||
case self::COMPRESSION_GZIP:
|
||||
return gzencode($value);
|
||||
case self::COMPRESSION_ZSTD:
|
||||
return zstd_compress($value);
|
||||
default:
|
||||
debugging("Invalid compressor: {$this->compressor}");
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uncompresses session data.
|
||||
*
|
||||
* @param string $value
|
||||
* @return mixed
|
||||
*/
|
||||
private function uncompress($value) {
|
||||
if ($value === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($this->compressor) {
|
||||
case self::COMPRESSION_NONE:
|
||||
break;
|
||||
case self::COMPRESSION_GZIP:
|
||||
$value = gzdecode($value);
|
||||
break;
|
||||
case self::COMPRESSION_ZSTD:
|
||||
$value = zstd_uncompress($value);
|
||||
break;
|
||||
default:
|
||||
debugging("Invalid compressor: {$this->compressor}");
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the serialized session data to our session store.
|
||||
*
|
||||
@@ -312,6 +379,8 @@ class redis extends handler {
|
||||
// There can be race conditions on new sessions racing each other but we can
|
||||
// address that in the future.
|
||||
try {
|
||||
$data = $this->compress($data);
|
||||
|
||||
$this->connection->setex($id, $this->timeout, $data);
|
||||
} catch (RedisException $e) {
|
||||
error_log('Failed talking to redis: '.$e->getMessage());
|
||||
|
||||
Reference in New Issue
Block a user