From 5fca27fd34e84c3d54ad2dd1894cf9d46a2ab819 Mon Sep 17 00:00:00 2001 From: yellow1912 Date: Tue, 17 Apr 2018 22:04:43 +0700 Subject: [PATCH] Add Serialization option (#411) * Add Serialization option Serialization option is necessary for setting the type of serialization to use for redis. This is simply a new commit with all the code taken from PR#199 using the latest code of SncRedisBundle on branch 2.1 * Minor code style update. Remove HHVM support * Switch to using Redis Class Constants instead of hard-coded values * Fix IGBINARY Dependency * Remove ?? to support php5 --- .../Configuration/Configuration.php | 1 + DependencyInjection/SncRedisExtension.php | 42 ++++++++++++++++- Resources/config/schema/redis-1.0.xsd | 10 ++++ .../SncRedisExtensionTest.php | 46 +++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) diff --git a/DependencyInjection/Configuration/Configuration.php b/DependencyInjection/Configuration/Configuration.php index 8636bb7f..90c94c1b 100644 --- a/DependencyInjection/Configuration/Configuration.php +++ b/DependencyInjection/Configuration/Configuration.php @@ -114,6 +114,7 @@ private function addClientsSection(ArrayNodeDefinition $rootNode) ->scalarNode('read_write_timeout')->defaultNull()->end() ->booleanNode('iterable_multibulk')->defaultFalse()->end() ->booleanNode('throw_errors')->defaultTrue()->end() + ->scalarNode('serialization')->defaultValue('default')->end() ->scalarNode('profile')->defaultValue('default') ->end() ->scalarNode('cluster')->defaultNull()->end() diff --git a/DependencyInjection/SncRedisExtension.php b/DependencyInjection/SncRedisExtension.php index c85ca63a..d04844cb 100644 --- a/DependencyInjection/SncRedisExtension.php +++ b/DependencyInjection/SncRedisExtension.php @@ -297,6 +297,12 @@ protected function loadPhpredisClient(array $client, ContainerBuilder $container if (null !== $dsn->getDatabase()) { $phpredisDef->addMethodCall('select', array($dsn->getDatabase())); } + if ($client['options']['serialization']) { + $phpredisDef->addMethodCall( + 'setOption', + array(\Redis::OPT_SERIALIZER, $this->loadSerializationType($client['options']['serialization'])) + ); + } $container->setDefinition($phpredisId, $phpredisDef); $container->setAlias(sprintf('snc_redis.%s', $client['alias']), $phpredisId); @@ -427,7 +433,41 @@ protected function loadSwiftMailer(array $config, ContainerBuilder $container) } /** - * Loads the profiler storage configuration. + * Load the correct serializer for Redis + * + * @param string $type + * + * @return string + * @throws InvalidConfigurationException + */ + public function loadSerializationType($type) + { + $types = array( + 'none' => \Redis::SERIALIZER_NONE, + 'php' => \Redis::SERIALIZER_PHP + ); + + if (defined('Redis::SERIALIZER_IGBINARY')) { + $types['igbinary'] = \Redis::SERIALIZER_IGBINARY; + } + + // allow user to pass in default serialization in which case we should automatically decide for them + if ('default' == $type) { + return isset($types['igbinary']) ? $types['igbinary'] : $types['php']; + } elseif (array_key_exists($type, $types)) { + return $types[$type]; + } + + throw new InvalidConfigurationException( + sprintf( + '%s in not a valid serializer. Valid serializers: %s', + $type, + implode(", ", array_keys($types)) + ) + ); + } + + /* Loads the profiler storage configuration. * * @param array $config A configuration array * @param ContainerBuilder $container A ContainerBuilder instance diff --git a/Resources/config/schema/redis-1.0.xsd b/Resources/config/schema/redis-1.0.xsd index 068d00ca..e8c25d6f 100644 --- a/Resources/config/schema/redis-1.0.xsd +++ b/Resources/config/schema/redis-1.0.xsd @@ -56,12 +56,22 @@ + + + + + + + + + + diff --git a/Tests/DependencyInjection/SncRedisExtensionTest.php b/Tests/DependencyInjection/SncRedisExtensionTest.php index fb4e7263..abbfeda2 100644 --- a/Tests/DependencyInjection/SncRedisExtensionTest.php +++ b/Tests/DependencyInjection/SncRedisExtensionTest.php @@ -308,6 +308,37 @@ public function testClientReplicationOption() $this->assertEquals(array('snc_redis.default' => array(array('alias' => 'default'))), $container->findTaggedServiceIds('snc_redis.client')); } + /** + * Test valid config of the serialization option + */ + public function testClientSerializationOption() + { + $extension = new SncRedisExtension(); + $config = $this->parseYaml($this->getSerializationYamlConfig()); + $extension->load(array($config), $container = $this->getContainer()); + $options = $container->getDefinition('snc_redis.client.default_options')->getArgument(0); + $parameters = $container->getDefinition('snc_redis.default')->getArgument(0); + $masterParameters = $container->getDefinition((string) $parameters[0])->getArgument(0); + $this->assertSame($options['serialization'], $masterParameters['serialization']); + } + + /** + * Test validity of serialization type + */ + public function testLoadSerializationType() + { + $extension = new SncRedisExtension(); + $config = $this->parseYaml($this->getSerializationYamlConfig()); + $extension->load(array($config), $container = $this->getContainer()); + $options = $container->getDefinition('snc_redis.client.default_options')->getArgument(0); + $serializationType = $extension->loadSerializationType($options['serialization']); + $this->assertTrue(is_integer($serializationType)); + + $defaultType = defined('Redis::SERIALIZER_IGBINARY') ? 2 : 1; + + $this->assertEquals($defaultType, $serializationType); + } + /** * Test valid config of the sentinel replication option */ @@ -361,6 +392,21 @@ private function parseYaml($yaml) return $parser->parse($yaml); } + private function getSerializationYamlConfig() + { + return <<<'EOF' +clients: + default: + type: predis + alias: default + dsn: + - redis://localhost?alias=master + - redis://otherhost + options: + serialization: "default" +EOF; + } + private function getMinimalYamlConfig() { return <<<'EOF'