123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- <?php
- namespace OC;
- use OCP\Diagnostics\IEventLogger;
- class RedisFactory {
- public const REDIS_MINIMAL_VERSION = '4.0.0';
- public const REDIS_EXTRA_PARAMETERS_MINIMAL_VERSION = '5.3.0';
-
- private $instance;
- private SystemConfig $config;
- private IEventLogger $eventLogger;
-
- public function __construct(SystemConfig $config, IEventLogger $eventLogger) {
- $this->config = $config;
- $this->eventLogger = $eventLogger;
- }
- private function create() {
- $isCluster = in_array('redis.cluster', $this->config->getKeys(), true);
- $config = $isCluster
- ? $this->config->getValue('redis.cluster', [])
- : $this->config->getValue('redis', []);
- if ($isCluster && !class_exists('RedisCluster')) {
- throw new \Exception('Redis Cluster support is not available');
- }
- $timeout = $config['timeout'] ?? 0.0;
- $readTimeout = $config['read_timeout'] ?? 0.0;
- $auth = null;
- if (isset($config['password']) && (string)$config['password'] !== '') {
- if (isset($config['user']) && (string)$config['user'] !== '') {
- $auth = [$config['user'], $config['password']];
- } else {
- $auth = $config['password'];
- }
- }
-
-
- $connectionParameters = $this->getSslContext($config);
- $persistent = $this->config->getValue('redis.persistent', true);
-
- if ($isCluster) {
- if (!isset($config['seeds'])) {
- throw new \Exception('Redis cluster config is missing the "seeds" attribute');
- }
-
- if ($connectionParameters !== null) {
- $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout, $persistent, $auth, $connectionParameters);
- } else {
- $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout, $persistent, $auth);
- }
- if (isset($config['failover_mode'])) {
- $this->instance->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, $config['failover_mode']);
- }
- } else {
- $this->instance = new \Redis();
- $host = $config['host'] ?? '127.0.0.1';
- $port = $config['port'] ?? ($host[0] !== '/' ? 6379 : null);
- $this->eventLogger->start('connect:redis', 'Connect to redis and send AUTH, SELECT');
-
- if ($connectionParameters !== null) {
-
- $connectionParameters = [
- 'stream' => $this->getSslContext($config)
- ];
- if ($persistent) {
-
- $this->instance->pconnect($host, $port, $timeout, null, 0, $readTimeout, $connectionParameters);
- } else {
- $this->instance->connect($host, $port, $timeout, null, 0, $readTimeout, $connectionParameters);
- }
- } else {
- if ($persistent) {
- $this->instance->pconnect($host, $port, $timeout, null, 0, $readTimeout);
- } else {
- $this->instance->connect($host, $port, $timeout, null, 0, $readTimeout);
- }
- }
-
- if ($auth !== null) {
- $this->instance->auth($auth);
- }
- if (isset($config['dbindex'])) {
- $this->instance->select($config['dbindex']);
- }
- $this->eventLogger->end('connect:redis');
- }
- }
-
- private function getSslContext($config) {
- if (isset($config['ssl_context'])) {
- if (!$this->isConnectionParametersSupported()) {
- throw new \UnexpectedValueException(\sprintf(
- 'php-redis extension must be version %s or higher to support ssl context',
- self::REDIS_EXTRA_PARAMETERS_MINIMAL_VERSION
- ));
- }
- return $config['ssl_context'];
- }
- return null;
- }
- public function getInstance() {
- if (!$this->isAvailable()) {
- throw new \Exception('Redis support is not available');
- }
- if (!$this->instance instanceof \Redis) {
- $this->create();
- }
- return $this->instance;
- }
- public function isAvailable(): bool {
- return \extension_loaded('redis') &&
- \version_compare(\phpversion('redis'), self::REDIS_MINIMAL_VERSION, '>=');
- }
-
- private function isConnectionParametersSupported(): bool {
- return \extension_loaded('redis') &&
- \version_compare(\phpversion('redis'), self::REDIS_EXTRA_PARAMETERS_MINIMAL_VERSION, '>=');
- }
- }
|