|
14 | 14 | use Predis\Connection\Factory; |
15 | 15 | use Predis\Connection\Aggregate\PredisCluster; |
16 | 16 | use Predis\Connection\Aggregate\RedisCluster; |
| 17 | +use Predis\Response\Status; |
17 | 18 | use Symfony\Component\Cache\Exception\InvalidArgumentException; |
18 | 19 |
|
19 | 20 | /** |
@@ -136,11 +137,14 @@ public static function createConnection($dsn, array $options = array()) |
136 | 137 | protected function doFetch(array $ids) |
137 | 138 | { |
138 | 139 | if ($ids) { |
139 | | - $values = $this->redis->mGet($ids); |
140 | | - $index = 0; |
141 | | - foreach ($ids as $id) { |
142 | | - if ($value = $values[$index++]) { |
143 | | - yield $id => parent::unserialize($value); |
| 140 | + $values = $this->pipeline(function () use ($ids) { |
| 141 | + foreach ($ids as $id) { |
| 142 | + yield 'get' => array($id); |
| 143 | + } |
| 144 | + }); |
| 145 | + foreach ($values as $id => $v) { |
| 146 | + if ($v) { |
| 147 | + yield $id => parent::unserialize($v); |
144 | 148 | } |
145 | 149 | } |
146 | 150 | } |
@@ -251,61 +255,60 @@ protected function doSave(array $values, $lifetime) |
251 | 255 | return $failed; |
252 | 256 | } |
253 | 257 |
|
254 | | - if (0 >= $lifetime) { |
255 | | - $this->redis->mSet($serialized); |
256 | | - |
257 | | - return $failed; |
258 | | - } |
259 | | - |
260 | | - $this->pipeline(function ($pipe) use (&$serialized, $lifetime) { |
| 258 | + $results = $this->pipeline(function () use ($serialized, $lifetime) { |
261 | 259 | foreach ($serialized as $id => $value) { |
262 | | - $pipe('setEx', $id, array($lifetime, $value)); |
| 260 | + if (0 >= $lifetime) { |
| 261 | + yield 'set' => array($id, $value); |
| 262 | + } else { |
| 263 | + yield 'setEx' => array($id, $lifetime, $value); |
| 264 | + } |
263 | 265 | } |
264 | 266 | }); |
| 267 | + foreach ($results as $id => $result) { |
| 268 | + if (true !== $result && (!$result instanceof Status || $result !== Status::get('OK'))) { |
| 269 | + $failed[] = $id; |
| 270 | + } |
| 271 | + } |
265 | 272 |
|
266 | 273 | return $failed; |
267 | 274 | } |
268 | 275 |
|
269 | | - private function execute($command, $id, array $args, $redis = null) |
| 276 | + private function pipeline(\Closure $generator) |
270 | 277 | { |
271 | | - array_unshift($args, $id); |
272 | | - call_user_func_array(array($redis ?: $this->redis, $command), $args); |
273 | | - } |
| 278 | + $ids = array(); |
274 | 279 |
|
275 | | - private function pipeline(\Closure $callback) |
276 | | - { |
277 | | - $redis = $this->redis; |
278 | | - |
279 | | - try { |
280 | | - if ($redis instanceof \Predis\Client) { |
281 | | - $redis->pipeline(function ($pipe) use ($callback) { |
282 | | - $this->redis = $pipe; |
283 | | - $callback(array($this, 'execute')); |
284 | | - }); |
285 | | - } elseif ($redis instanceof \RedisArray) { |
286 | | - $connections = array(); |
287 | | - $callback(function ($command, $id, $args) use (&$connections) { |
288 | | - if (!isset($connections[$h = $this->redis->_target($id)])) { |
289 | | - $connections[$h] = $this->redis->_instance($h); |
290 | | - $connections[$h]->multi(\Redis::PIPELINE); |
291 | | - } |
292 | | - $this->execute($command, $id, $args, $connections[$h]); |
293 | | - }); |
294 | | - foreach ($connections as $c) { |
295 | | - $c->exec(); |
| 280 | + if ($this->redis instanceof \Predis\Client) { |
| 281 | + $results = $this->redis->pipeline(function ($redis) use ($generator, &$ids) { |
| 282 | + foreach ($generator() as $command => $args) { |
| 283 | + call_user_func_array(array($redis, $command), $args); |
| 284 | + $ids[] = $args[0]; |
296 | 285 | } |
297 | | - } else { |
298 | | - $pipe = $redis->multi(\Redis::PIPELINE); |
299 | | - try { |
300 | | - $callback(array($this, 'execute')); |
301 | | - } finally { |
302 | | - if ($pipe) { |
303 | | - $redis->exec(); |
304 | | - } |
| 286 | + }); |
| 287 | + } elseif ($this->redis instanceof \RedisArray) { |
| 288 | + $connections = $results = $ids = array(); |
| 289 | + foreach ($generator() as $command => $args) { |
| 290 | + if (!isset($connections[$h = $this->redis->_target($args[0])])) { |
| 291 | + $connections[$h] = array($this->redis->_instance($h), array()); |
| 292 | + $connections[$h][0]->multi(\Redis::PIPELINE); |
305 | 293 | } |
| 294 | + call_user_func_array(array($connections[$h][0], $command), $args); |
| 295 | + $connections[$h][1][] = $args[0]; |
| 296 | + } |
| 297 | + foreach ($connections as $c) { |
| 298 | + $results = array_merge($results, $c[0]->exec()); |
| 299 | + $ids = array_merge($ids, $c[1]); |
306 | 300 | } |
307 | | - } finally { |
308 | | - $this->redis = $redis; |
| 301 | + } else { |
| 302 | + $this->redis->multi(\Redis::PIPELINE); |
| 303 | + foreach ($generator() as $command => $args) { |
| 304 | + call_user_func_array(array($this->redis, $command), $args); |
| 305 | + $ids[] = $args[0]; |
| 306 | + } |
| 307 | + $results = $this->redis->exec(); |
| 308 | + } |
| 309 | + |
| 310 | + foreach ($ids as $k => $id) { |
| 311 | + yield $id => $results[$k]; |
309 | 312 | } |
310 | 313 | } |
311 | 314 | } |
0 commit comments