mirror of
https://github.com/predis/predis.git
synced 2026-09-02 13:49:32 +00:00
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:
@@ -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,
|
||||
);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user