/
PhpRedisSentinelConnector.php
118 lines (101 loc) · 3.71 KB
/
PhpRedisSentinelConnector.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
declare(strict_types=1);
namespace Namoshek\Redis\Sentinel\Connectors;
use Illuminate\Redis\Connectors\PhpRedisConnector;
use Illuminate\Support\Arr;
use Namoshek\Redis\Sentinel\Connections\PhpRedisSentinelConnection;
use Namoshek\Redis\Sentinel\Exceptions\ConfigurationException;
use Namoshek\Redis\Sentinel\Exceptions\NotImplementedException;
use Redis;
use RedisException;
use RedisSentinel;
/**
* Allows to connect to a Sentinel driven Redis master using the PhpRedis extension.
*/
class PhpRedisSentinelConnector extends PhpRedisConnector
{
/**
* {@inheritdoc}
*
* @throws RedisException
*/
public function connect(array $config, array $options): PhpRedisSentinelConnection
{
$connector = function () use ($config, $options) {
return $this->createClient(array_merge(
$config,
$options,
Arr::pull($config, 'options', [])
));
};
return new PhpRedisSentinelConnection($connector(), $connector, $config);
}
/**
* {@inheritdoc}
*/
public function connectToCluster(array $config, array $clusterOptions, array $options)
{
throw new NotImplementedException('The Redis Sentinel driver does not support connecting to clusters.');
}
/**
* Create the PhpRedis client instance which connects to Redis Sentinel.
*
* @throws ConfigurationException
* @throws RedisException
*/
protected function createClient(array $config): Redis
{
$service = $config['sentinel_service'] ?? 'mymaster';
$sentinel = $this->connectToSentinel($config);
$master = $sentinel->master($service);
if ($master === false
|| ! is_array($master)
|| ! isset($master['ip'])
|| ! isset($master['port'])
) {
throw new RedisException(sprintf("No master found for service '%s'.", $service));
}
return parent::createClient(array_merge($config, [
'host' => $master['ip'],
'port' => $master['port'],
]));
}
/**
* Connect to the configured Redis Sentinel instance.
*
* @throws ConfigurationException
*/
private function connectToSentinel(array $config): RedisSentinel
{
$host = $config['sentinel_host'] ?? '';
$port = $config['sentinel_port'] ?? 26379;
$timeout = $config['sentinel_timeout'] ?? 0.2;
$persistent = $config['sentinel_persistent'] ?? null;
$retryInterval = $config['sentinel_retry_interval'] ?? 0;
$readTimeout = $config['sentinel_read_timeout'] ?? 0;
$password = $config['sentinel_password'] ?? '';
if (strlen(trim($host)) === 0) {
throw new ConfigurationException('No host has been specified for the Redis Sentinel connection.');
}
if (version_compare(phpversion('redis'), '6.0', '>=')) {
$options = [
'host' => $host,
'port' => $port,
'connectTimeout' => $timeout,
'persistent' => $persistent,
'retryInterval' => $retryInterval,
'readTimeout' => $readTimeout,
];
if (strlen(trim($password)) !== 0) {
$options['auth'] = $password;
}
return new RedisSentinel($options);
} else {
if (strlen(trim($password)) !== 0) {
/** @noinspection PhpMethodParametersCountMismatchInspection */
return new RedisSentinel($host, $port, $timeout, $persistent, $retryInterval, $readTimeout, $password);
}
return new RedisSentinel($host, $port, $timeout, $persistent, $retryInterval, $readTimeout);
}
}
}