Fix MONITOR and Predis\MonitorContext with Redis 2.6.

Starting with 2.6, Redis uses a slightly different format for the payload
returned by MONITOR for each command. Predis can now adapt to this difference
and returns a new `client` field in the payload object. This new field is
always defined but is set to NULL when connected to Redis < 2.6.

Please note that Redis 2.6 now does not echo the `MONITOR` command as the
first payload when opening a new MONITOR context.
This commit is contained in:
Daniele Alessandri
2012-03-11 17:39:57 +01:00
parent 7893fd1faa
commit 7b01bc0644
3 changed files with 43 additions and 6 deletions
+12 -4
View File
@@ -136,21 +136,29 @@ class MonitorContext implements \Iterator
private function getValue()
{
$database = 0;
$client = null;
$event = $this->client->getConnection()->read();
$callback = function($matches) use (&$database) {
if (isset($matches[1])) {
$callback = function($matches) use (&$database, &$client) {
if (2 === $count = count($matches)) {
// Redis <= 2.4
$database = (int) $matches[1];
}
if (4 === $count) {
// Redis >= 2.6
$database = (int) $matches[2];
$client = $matches[3];
}
return ' ';
};
$event = preg_replace_callback('/ \(db (\d+)\) /', $callback, $event, 1);
@list($timestamp, $command, $arguments) = split(' ', $event, 3);
$event = preg_replace_callback('/ \(db (\d+)\) | \[(\d+) (.*?)\] /', $callback, $event, 1);
@list($timestamp, $command, $arguments) = explode(' ', $event, 3);
return (object) array(
'timestamp' => (float) $timestamp,
'database' => $database,
'client' => $client,
'command' => substr($command, 1, -1),
'arguments' => $arguments,
);
+6 -1
View File
@@ -64,6 +64,11 @@ class ServerMonitorTest extends CommandTestCase
$command = $this->getCommand();
$this->assertTrue($connection->executeCommand($command));
$this->assertRegExp('/\d+.\d+(\s?\(db \d+\))? "MONITOR"/', $connection->read());
// NOTE: Starting with 2.6 Redis does not return the "MONITOR" message after
// +OK to the client that issued the MONITOR command.
if (version_compare($this->getProfile()->getVersion(), '2.4', '<=')) {
$this->assertRegExp('/\d+.\d+(\s?\(db \d+\))? "MONITOR"/', $connection->read());
}
}
}
+25 -1
View File
@@ -106,7 +106,7 @@ class MonitorContextTest extends StandardTestCase
/**
* @group disconnected
*/
public function testCurrentReadsMessageFromConnection()
public function testReadsMessageFromConnectionToRedis24()
{
$message = '1323367530.939137 (db 15) "MONITOR"';
@@ -121,6 +121,30 @@ class MonitorContextTest extends StandardTestCase
$payload = $monitor->current();
$this->assertSame(1323367530, (int) $payload->timestamp);
$this->assertSame(15, $payload->database);
$this->assertNull($payload->client);
$this->assertSame('MONITOR', $payload->command);
$this->assertNull($payload->arguments);
}
/**
* @group disconnected
*/
public function testReadsMessageFromConnectionToRedis26()
{
$message = '1323367530.939137 [15 127.0.0.1:37265] "MONITOR"';
$connection = $this->getMock('Predis\Connection\SingleConnectionInterface');
$connection->expects($this->once())
->method('read')
->will($this->returnValue($message));
$client = new Client($connection);
$monitor = new MonitorContext($client);
$payload = $monitor->current();
$this->assertSame(1323367530, (int) $payload->timestamp);
$this->assertSame(15, $payload->database);
$this->assertSame('127.0.0.1:37265', $payload->client);
$this->assertSame('MONITOR', $payload->command);
$this->assertNull($payload->arguments);
}