8000 [Cache] Cleanups · symfony/symfony@9a56498 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9a56498

Browse files
[Cache] Cleanups
1 parent 8166094 commit 9a56498

File tree

3 files changed

+40
-34
lines changed

3 files changed

+40
-34
lines changed

src/Symfony/Component/Cache/Adapter/AbstractAdapter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,15 @@ public function getItems(array $keys = array())
149149
$ids = array();
150150

151151
foreach ($keys as $key) {
152-
$ids[$key] = $this->getId($key);
152+
$ids[] = $this->getId($key);
153153
}
154154
try {
155155
$items = $this->doFetch($ids);
156156
} catch (\Exception $e) {
157157
CacheItem::log($this->logger, 'Failed to fetch requested items', array('keys' => $keys, 'exception' => $e));
158158
$items = array();
159159
}
160-
$ids = array_flip($ids);
160+
$ids = array_combine($ids, $keys);
161161

162162
return $this->generateItems($items, $ids);
163163
}

src/Symfony/Component/Cache/Adapter/RedisAdapter.php

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ class RedisAdapter extends AbstractAdapter
2727
);
2828
private $redis;
2929

30-
public function __construct(\Redis $redisConnection, $namespace = '', $defaultLifetime = 0)
30+
public function __construct(\Redis $redisClient, $namespace = '', $defaultLifetime = 0)
3131
{
32+
parent::__construct($namespace, $defaultLifetime);
33+
3234
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
3335
throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
3436
}
35-
$this->redis = $redisConnection;
36-
37-
parent::__construct($namespace, $defaultLifetime);
37+
$this->redis = $redisClient;
3838
}
3939

4040
/**
@@ -86,26 +86,29 @@ public static function createConnection($dsn, array $options = array())
8686
$params += $query;
8787
}
8888
$params += $options + self::$defaultConnectionOptions;
89+
$class = $params['class'];
8990

90-
if (\Redis::class !== $params['class'] && !is_subclass_of($params['class'], \Redis::class)) {
91-
throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis"', $params['class']));
92-
}
93-
$connect = empty($params['persistent']) ? 'connect' : 'pconnect';
94-
$redis = new $params['class']();
95-
@$redis->{$connect}($params['host'], $params['port'], $params['timeout'], null, $params['retry_interval']);
91+
if (is_a($class, \Redis::class, true)) {
92+
$connect = empty($params['persistent']) ? 'connect' : 'pconnect';
93+
$redis = new $class();
94+
@$redis->{$connect}($params['host'], $params['port'], $params['timeout'], null, $params['retry_interval']);
9695

97-
if (@!$redis->isConnected()) {
98-
$e = ($e = error_get_last()) && preg_match('/^Redis::p?connect\(\): (.*)/', $e['message'], $e) ? sprintf(' (%s)', $e[1]) : '';
99-
throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $e, $dsn));
100-
}
96+
if (@!$redis->isConnected()) {
97+
$e = ($e = error_get_last()) && preg_match('/^Redis::p?connect\(\): (.*)/', $e['message'], $e) ? sprintf(' (%s)', $e[1]) : '';
98+
throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $e, $dsn));
99+
}
101100

102-
if ((null !== $auth && !$redis->auth($auth))
103-
|| ($params['dbindex'] && !$redis->select($params['dbindex']))
104-
|| ($params['read_timeout'] && !$redis->setOption(\Redis::OPT_READ_TIMEOUT, $params['read_timeout']))
105-
) {
106-
$e = preg_replace('/^ERR /', '', $redis->getLastError());
107-
$redis->close();
108-
throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e, $dsn));
101+
if ((null !== $auth && !$redis->auth($auth))
102+
|| ($params['dbindex'] && !$redis->select($params['dbindex']))
103+
|| ($params['read_timeout'] && !$redis->setOption(\Redis::OPT_READ_TIMEOUT, $params['read_timeout']))
104+
) {
105+
$e = preg_replace('/^ERR /', '', $redis->getLastError());
106+
throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e, $dsn));
107+
}
108+
} elseif (class_exists($class, false)) {
109+
throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis"', $class));
110+
} else {
111+
throw new InvalidArgumentException(sprintf('Class "%s" does not exist', $class));
109112
}
110113

111114
return $redis;
@@ -119,10 +122,10 @@ protected function doFetch(array $ids)
119122
$result = array();
120123

121124
if ($ids) {
122-
$values = $this->redis->mget($ids);
125+
$values = $this->redis->mGet($ids);
123126
$index = 0;
124127
foreach ($ids as $id) {
125-
if (false !== $value = $values[$index++]) {
128+
if ($value = $values[$index++]) {
126129
$result[$id] = unserialize($value);
127130
}
128131
}
@@ -144,14 +147,16 @@ protected function doHave($id)
144147
*/
145148
protected function doClear($namespace)
146149
{
150+
// As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
151+
// can hang your server when it is executed against large databases (millions of items).
152+
// Whenever you hit this scale, it is advised to deploy one Redis database per cache pool
153+
// instead of using namespaces, so that FLUSHDB is used instead.
154+
$lua = "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";
155+
147156
if (!isset($namespace[0])) {
148-
$this->redis->flushDB();
157+
$this->redis->flushDb();
149158
} else {
150-
// As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
151-
// can hang your server when it is executed against large databases (millions of items).
152-
// Whenever you hit this scale, it is advised to deploy one Redis database per cache pool
153-
// instead of using namespaces, so that the above FLUSHDB is used instead.
154-
$this->redis->eval(sprintf("local keys=redis.call('KEYS','%s*') for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end", $namespace));
159+
$this->redis->eval($lua, array($namespace), 0);
155160
}
156161

157162
return true;
@@ -189,11 +194,11 @@ protected function doSave(array $values, $lifetime)
189194
return $failed;
190195
}
191196
if ($lifetime > 0) {
192-
$pipe = $this->redis->multi(\Redis::PIPELINE);
197+
$this->redis->multi(\Redis::PIPELINE);
193198
foreach ($serialized as $id => $value) {
194-
$pipe->setEx($id, $lifetime, $value);
199+
$this->redis->setEx($id, $lifetime, $value);
195200
}
196-
if (!$pipe->exec()) {
201+
if (!$this->redis->exec()) {
197202
return false;
198203
}
199204
} elseif (!$this->redis->mSet($serialized)) {

src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public static function tearDownAfterClass()
4848
public function testCreateConnection()
4949
{
5050
$redis = RedisAdapter::createConnection('redis://localhost');
51+
$this->assertInstanceOf(\Redis::class, $redis);
5152
$this->assertTrue($redis->isConnected());
5253
$this->assertSame(0, $redis->getDbNum());
5354

0 commit comments

Comments
 (0)
0