|
12 | 12 | namespace Symfony\Component\Cache\Adapter;
|
13 | 13 |
|
14 | 14 | use Predis\Connection\Factory;
|
15 |
| -use Predis\Connection\Aggregate\PredisCluster; |
16 |
| -use Predis\Connection\Aggregate\RedisCluster; |
17 | 15 | use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
18 | 16 |
|
19 | 17 | /**
|
|
22 | 20 | */
|
23 | 21 | class RedisAdapter extends AbstractAdapter
|
24 | 22 | {
|
| 23 | + use RedisAdapterTrait; |
| 24 | + |
25 | 25 | private static $defaultConnectionOptions = array(
|
26 | 26 | 'class' => null,
|
27 | 27 | 'persistent' => 0,
|
28 | 28 | 'timeout' => 0,
|
29 | 29 | 'read_timeout' => 0,
|
30 | 30 | 'retry_interval' => 0,
|
31 | 31 | );
|
32 |
| - private $redis; |
33 | 32 |
|
34 | 33 | /**
|
35 | 34 | * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient
|
36 | 35 | */
|
37 | 36 | public function __construct($redisClient, $namespace = '', $defaultLifetime = 0)
|
38 | 37 | {
|
39 | 38 | parent::__construct($namespace, $defaultLifetime);
|
40 |
| - |
41 |
| - if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { |
42 |
| - throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); |
43 |
| - } |
44 |
| - if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client) { |
45 |
| - throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, is_object($redisClient) ? get_class($redisClient) : gettype($redisClient))); |
46 |
| - } |
47 |
| - $this->redis = $redisClient; |
| 39 | + $this->setRedis($redisClient, $namespace); |
48 | 40 | }
|
49 | 41 |
|
50 | 42 | /**
|
@@ -157,51 +149,6 @@ protected function doHave($id)
|
157 | 149 | return (bool) $this->redis->exists($id);
|
158 | 150 | }
|
159 | 151 |
|
160 |
| - /** |
161 |
| - * {@inheritdoc} |
162 |
| - */ |
163 |
| - protected function doClear($namespace) |
164 |
| - { |
165 |
| - // When using a native Redis cluster, clearing the cache cannot work and always returns false. |
166 |
| - // Clearing the cache should then be done by any other means (e.g. by restarting the cluster). |
167 |
| - |
168 |
| - $hosts = array($this->redis); |
169 |
| - $evalArgs = array(array($namespace), 0); |
170 |
| - |
171 |
| - if ($this->redis instanceof \Predis\Client) { |
172 |
| - $evalArgs = array(0, $namespace); |
173 |
| - |
174 |
| - $connection = $this->redis->getConnection(); |
175 |
| - if ($connection instanceof PredisCluster) { |
176 |
| - $hosts = array(); |
177 |
| - foreach ($connection as $c) { |
178 |
| - $hosts[] = new \Predis\Client($c); |
179 |
| - } |
180 |
| - } elseif ($connection instanceof RedisCluster) { |
181 |
| - return false; |
182 |
| - } |
183 |
| - } elseif ($this->redis instanceof \RedisArray) { |
184 |
| - foreach ($this->redis->_hosts() as $host) { |
185 |
| - $hosts[] = $this->redis->_instance($host); |
186 |
| - } |
187 |
| - } elseif ($this->redis instanceof \RedisCluster) { |
188 |
| - return false; |
189 |
| - } |
190 |
| - foreach ($hosts as $host) { |
191 |
| - if (!isset($namespace[0])) { |
192 |
| - $host->flushDb(); |
193 |
| - } else { |
194 |
| - // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS |
195 |
| - // can hang your server when it is executed against large databases (millions of items). |
196 |
| - // Whenever you hit this scale, it is advised to deploy one Redis database per cache pool |
197 |
| - // instead of using namespaces, so that FLUSHDB is used instead. |
198 |
| - $host->eval("local keys=redis.call('KEYS',ARGV[1]..'*') for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end", $evalArgs[0], $evalArgs[1]); |
199 |
| - } |
200 |
| - } |
201 |
| - |
202 |
| - return true; |
203 |
| - } |
204 |
| - |
205 | 152 | /**
|
206 | 153 | * {@inheritdoc}
|
207 | 154 | */
|
@@ -248,47 +195,4 @@ protected function doSave(array $values, $lifetime)
|
248 | 195 |
|
249 | 196 | return $failed;
|
250 | 197 | }
|
251 |
| - |
252 |
| - private function execute($command, $id, array $args, $redis = null) |
253 |
| - { |
254 |
| - array_unshift($args, $id); |
255 |
| - call_user_func_array(array($redis ?: $this->redis, $command), $args); |
256 |
| - } |
257 |
| - |
258 |
| - private function pipeline(\Closure $callback) |
259 |
| - { |
260 |
| - $redis = $this->redis; |
261 |
| - |
262 |
| - try { |
263 |
| - if ($redis instanceof \Predis\Client) { |
264 |
| - $redis->pipeline(function ($pipe) use ($callback) { |
265 |
| - $this->redis = $pipe; |
266 |
| - $callback(array($this, 'execute')); |
267 |
| - }); |
268 |
| - } elseif ($redis instanceof \RedisArray) { |
269 |
| - $connections = array(); |
270 |
| - $callback(function ($command, $id, $args) use (&$connections) { |
271 |
| - if (!isset($connections[$h = $this->redis->_target($id)])) { |
272 |
| - $connections[$h] = $this->redis->_instance($h); |
273 |
| - $connections[$h]->multi(\Redis::PIPELINE); |
274 |
| - } |
275 |
| - $this->execute($command, $id, $args, $connections[$h]); |
276 |
| - }); |
277 |
| - foreach ($connections as $c) { |
278 |
| - $c->exec(); |
279 |
| - } |
280 |
| - } else { |
281 |
| - $pipe = $redis->multi(\Redis::PIPELINE); |
282 |
| - try { |
283 |
| - $callback(array($this, 'execute')); |
284 |
| - } finally { |
285 |
| - if ($pipe) { |
286 |
| - $redis->exec(); |
287 |
| - } |
288 |
| - } |
289 |
| - } |
290 |
| - } finally { |
291 |
| - $this->redis = $redis; |
292 |
| - } |
293 |
| - } |
294 | 198 | }
|
0 commit comments