From 9c860cea46cb3cec9aa4b271c02aa71c4006c9f6 Mon Sep 17 00:00:00 2001 From: wehr Date: Thu, 5 Jan 2017 21:13:31 +0100 Subject: [PATCH] MDL-57572 cache: Adds igbinary serializer to Redis cache store --- cache/stores/redis/addinstanceform.php | 6 +++ .../stores/redis/lang/en/cachestore_redis.php | 12 +++++- cache/stores/redis/lib.php | 42 +++++++++++++++++-- cache/stores/redis/settings.php | 31 ++++++++++---- 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/cache/stores/redis/addinstanceform.php b/cache/stores/redis/addinstanceform.php index 537cbef1a34..8da4f1e3577 100644 --- a/cache/stores/redis/addinstanceform.php +++ b/cache/stores/redis/addinstanceform.php @@ -48,5 +48,11 @@ class cachestore_redis_addinstance_form extends cachestore_addinstance_form { $form->setType('prefix', PARAM_TEXT); // We set to text but we have a rule to limit to alphanumext. $form->addHelpButton('prefix', 'prefix', 'cachestore_redis'); $form->addRule('prefix', get_string('prefixinvalid', 'cachestore_redis'), 'regex', '#^[a-zA-Z0-9\-_]+$#'); + + $serializeroptions = cachestore_redis::config_get_serializer_options(); + $form->addElement('select', 'serializer', get_string('useserializer', 'cachestore_redis'), $serializeroptions); + $form->addHelpButton('serializer', 'useserializer', 'cachestore_redis'); + $form->setDefault('serializer', Redis::SERIALIZER_PHP); + $form->setType('serializer', PARAM_INT); } } \ No newline at end of file diff --git a/cache/stores/redis/lang/en/cachestore_redis.php b/cache/stores/redis/lang/en/cachestore_redis.php index e51e19f2f99..a44a1562e37 100644 --- a/cache/stores/redis/lang/en/cachestore_redis.php +++ b/cache/stores/redis/lang/en/cachestore_redis.php @@ -30,7 +30,15 @@ $string['prefix_help'] = 'This prefix is used for all key names on the Redis ser * If you only have one Moodle instance using this server, you can leave this value default. * Due to key length restrictions, a maximum of 5 characters is permitted.'; $string['prefixinvalid'] = 'Invalid prefix. You can only use a-z A-Z 0-9-_.'; +$string['serializer_igbinary'] = 'The igbinary serializer.'; +$string['serializer_php'] = 'The default PHP serializer.'; +$string['server'] = 'Server'; +$string['server_help'] = 'This sets the hostname or IP address of the Redis server to use.'; $string['test_server'] = 'Test server'; $string['test_server_desc'] = 'Redis server to use for testing.'; -$string['server'] = 'Server'; -$string['server_help'] = 'This sets the hostname or IP address of the Redis server to use.'; \ No newline at end of file +$string['test_serializer'] = 'Serializer'; +$string['test_serializer_desc'] = 'Serializer to use for testing.'; +$string['useserializer'] = 'Use serializer'; +$string['useserializer_help'] = 'Specifies the serializer to use for serializing. +The valid serializers are Redis::SERIALIZER_PHP or Redis::SERIALIZER_IGBINARY. +The latter is supported only when phpredis is configured with --enable-redis-igbinary option and the igbinary extension is loaded.'; diff --git a/cache/stores/redis/lib.php b/cache/stores/redis/lib.php index 16ad4c298e2..fd19709ecf6 100644 --- a/cache/stores/redis/lib.php +++ b/cache/stores/redis/lib.php @@ -73,6 +73,13 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ */ protected $redis; + /** + * Serializer for this store. + * + * @var int + */ + protected $serializer = Redis::SERIALIZER_PHP; + /** * Determines if the requirements for this type of store are met. * @@ -124,6 +131,9 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ if (!array_key_exists('server', $configuration) || empty($configuration['server'])) { return; } + if (array_key_exists('serializer', $configuration)) { + $this->serializer = (int)$configuration['serializer']; + } $prefix = !empty($configuration['prefix']) ? $configuration['prefix'] : ''; $this->redis = $this->new_redis($configuration['server'], $prefix); } @@ -145,7 +155,7 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ $port = $serverconf[1]; } if ($redis->connect($server, $port)) { - $redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP); + $redis->setOption(Redis::OPT_SERIALIZER, $this->serializer); if (!empty($prefix)) { $redis->setOption(Redis::OPT_PREFIX, $prefix); } @@ -426,7 +436,11 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ * @return array */ public static function config_get_configuration_array($data) { - return array('server' => $data->server, 'prefix' => $data->prefix); + return array( + 'server' => $data->server, + 'prefix' => $data->prefix, + 'serializer' => $data->serializer + ); } /** @@ -440,6 +454,9 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ $data = array(); $data['server'] = $config['server']; $data['prefix'] = !empty($config['prefix']) ? $config['prefix'] : ''; + if (!empty($config['serializer'])) { + $data['serializer'] = $config['serializer']; + } $editform->set_data($data); } @@ -458,7 +475,11 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ if (empty($config->test_server)) { return false; } - $cache = new cachestore_redis('Redis test', ['server' => $config->test_server]); + $configuration = array('server' => $config->test_server); + if (!empty($config->test_serializer)) { + $configuration['serializer'] = $config->test_serializer; + } + $cache = new cachestore_redis('Redis test', $configuration); $cache->initialise($definition); return $cache; @@ -491,4 +512,19 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_ public static function ready_to_be_used_for_testing() { return defined('TEST_CACHESTORE_REDIS_TESTSERVERS'); } + + /** + * Gets an array of options to use as the serialiser. + * @return array + */ + public static function config_get_serializer_options() { + $options = array( + Redis::SERIALIZER_PHP => get_string('serializer_php', 'cachestore_redis') + ); + + if (defined('Redis::SERIALIZER_IGBINARY')) { + $options[Redis::SERIALIZER_IGBINARY] = get_string('serializer_igbinary', 'cachestore_redis'); + } + return $options; + } } diff --git a/cache/stores/redis/settings.php b/cache/stores/redis/settings.php index 1d10cf81e0a..92c9c1ddf85 100644 --- a/cache/stores/redis/settings.php +++ b/cache/stores/redis/settings.php @@ -25,12 +25,27 @@ defined('MOODLE_INTERNAL') || die(); $settings->add( - new admin_setting_configtext( - 'cachestore_redis/test_server', - get_string('test_server', 'cachestore_redis'), - get_string('test_server_desc', 'cachestore_redis'), - '', - PARAM_TEXT, - 16 - ) + new admin_setting_configtext( + 'cachestore_redis/test_server', + get_string('test_server', 'cachestore_redis'), + get_string('test_server_desc', 'cachestore_redis'), + '', + PARAM_TEXT, + 16 + ) ); + +$options = array(Redis::SERIALIZER_PHP => get_string('serializer_php', 'cachestore_redis')); + +if (defined('Redis::SERIALIZER_IGBINARY')) { + $options[Redis::SERIALIZER_IGBINARY] = get_string('serializer_igbinary', 'cachestore_redis'); +} + +$settings->add(new admin_setting_configselect( + 'cachestore_redis/test_serializer', + get_string('test_serializer', 'cachestore_redis'), + get_string('test_serializer_desc', 'cachestore_redis'), + 0, + $options + ) +); \ No newline at end of file