diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php index 874dec0b87..40163e5e43 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php @@ -132,11 +132,8 @@ class FilesystemAdapter extends AbstractAdapter $expiresAt = $lifetime ? time() + $lifetime : PHP_INT_MAX; foreach ($values as $id => $value) { - $file = $this->getFile($id); - $dir = dirname($file); - if (!file_exists($dir)) { - @mkdir($dir, 0777, true); - } + $file = $this->getFile($id, true); + $value = $expiresAt."\n".rawurlencode($id)."\n".serialize($value); if (false !== @file_put_contents($file, $value, LOCK_EX)) { @touch($file, $expiresAt); @@ -148,10 +145,15 @@ class FilesystemAdapter extends AbstractAdapter return $ok; } - private function getFile($id) + private function getFile($id, $mkdir = false) { $hash = str_replace('/', '-', base64_encode(md5($id, true))); + $dir = $this->directory.$hash[0].DIRECTORY_SEPARATOR.$hash[1].DIRECTORY_SEPARATOR; - return $this->directory.$hash[0].DIRECTORY_SEPARATOR.$hash[1].DIRECTORY_SEPARATOR.substr($hash, 2, -2); + if ($mkdir && !file_exists($dir)) { + @mkdir($dir, 0777, true); + } + + return $dir.substr($hash, 2, -2); } } diff --git a/src/Symfony/Component/Cache/Adapter/RedisAdapter.php b/src/Symfony/Component/Cache/Adapter/RedisAdapter.php index ab0b86e434..92c065ebf7 100644 --- a/src/Symfony/Component/Cache/Adapter/RedisAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/RedisAdapter.php @@ -233,51 +233,62 @@ class RedisAdapter extends AbstractAdapter if (!$serialized) { return $failed; } - if ($lifetime > 0) { - if ($this->redis instanceof \RedisArray) { - $redis = array(); - foreach ($serialized as $id => $value) { - if (!isset($redis[$h = $this->redis->_target($id)])) { - $redis[$h] = $this->redis->_instance($h); - $redis[$h]->multi(\Redis::PIPELINE); - } - $redis[$h]->setEx($id, $lifetime, $value); - } - foreach ($redis as $h) { - if (!$h->exec()) { - $failed = false; - } - } - } else { - $this->pipeline(function ($pipe) use ($serialized, $lifetime) { - foreach ($serialized as $id => $value) { - $pipe->setEx($id, $lifetime, $value); - } - }); - } - } elseif (!$this->redis->mSet($serialized)) { - return false; + + if (0 >= $lifetime) { + $this->redis->mSet($serialized); + + return $failed; } + $this->pipeline(function ($pipe) use (&$serialized, $lifetime) { + foreach ($serialized as $id => $value) { + $pipe('setEx', $id, array($lifetime, $value)); + } + }); + return $failed; } + private function execute($command, $id, array $args, $redis = null) + { + array_unshift($args, $id); + call_user_func_array(array($redis ?: $this->redis, $command), $args); + } + private function pipeline(\Closure $callback) { - if ($this->redis instanceof \Predis\Client) { - return $this->redis->pipeline($callback); - } - $pipe = $this->redis instanceof \Redis && $this->redis->multi(\Redis::PIPELINE); + $redis = $this->redis; + try { - $e = null; - $callback($this->redis); - } catch (\Exception $e) { - } - if ($pipe) { - $this->redis->exec(); - } - if (null !== $e) { - throw $e; + if ($redis instanceof \Predis\Client) { + $redis->pipeline(function ($pipe) use ($callback) { + $this->redis = $pipe; + $callback(array($this, 'execute')); + }); + } elseif ($redis instanceof \RedisArray) { + $connections = array(); + $callback(function ($command, $id, $args) use (&$connections) { + if (!isset($connections[$h = $this->redis->_target($id)])) { + $connections[$h] = $this->redis->_instance($h); + $connections[$h]->multi(\Redis::PIPELINE); + } + $this->execute($command, $id, $args, $connections[$h]); + }); + foreach ($connections as $c) { + $c->exec(); + } + } else { + $pipe = $redis->multi(\Redis::PIPELINE); + try { + $callback(array($this, 'execute')); + } finally { + if ($pipe) { + $redis->exec(); + } + } + } + } finally { + $this->redis = $redis; } } }