From f87e0d53998e242ccd3724ed854ec77eadf4ca59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 26 Jul 2014 01:18:46 +0200 Subject: [PATCH 1/5] Split off ResponseApi from Client. Handling the Request-Response pattern has been moved to a dedicated ResponseApi class. This helps keeping concerns separated and prepares this project to support the PubSub pattern. --- example/cli.php | 4 +- example/incr.php | 9 ++-- src/Client.php | 68 ++-------------------------- src/Factory.php | 6 ++- src/ResponseApi.php | 95 +++++++++++++++++++++++++++++++++++++++ tests/ClientTest.php | 79 ++++++++++++++++++++++++++++++++ tests/FunctionalTest.php | 45 +++++++++++-------- tests/ResponseApiTest.php | 95 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 311 insertions(+), 90 deletions(-) create mode 100644 src/ResponseApi.php create mode 100644 tests/ClientTest.php create mode 100644 tests/ResponseApiTest.php diff --git a/example/cli.php b/example/cli.php index 80c24c7..6b01f15 100644 --- a/example/cli.php +++ b/example/cli.php @@ -30,7 +30,7 @@ $line = fgets(STDIN); if ($line === false || $line === '') { echo '# CTRL-D -> Ending connection...' . PHP_EOL; - $client->end(); + $client->close(); } else { $line = rtrim($line); @@ -39,7 +39,7 @@ } else { $params = explode(' ', $line); $method = array_shift($params); - call_user_func_array(array($client, $method), $params); + $client->send($method, $params); } } }); diff --git a/example/incr.php b/example/incr.php index 2ef0d3c..b2b84e1 100644 --- a/example/incr.php +++ b/example/incr.php @@ -2,6 +2,7 @@ use Clue\React\Redis\Client; use Clue\React\Redis\Factory; +use Clue\React\Redis\ResponseApi; require __DIR__ . '/../vendor/autoload.php'; @@ -12,13 +13,15 @@ $factory = new Factory($connector); $factory->createClient()->then(function (Client $client) { - $client->incr('test'); + $api = new ResponseApi($client); - $client->get('test')->then(function ($result) { + $api->incr('test'); + + $api->get('test')->then(function ($result) { var_dump($result); }); - $client->end(); + $api->end(); }); $loop->run(); diff --git a/src/Client.php b/src/Client.php index 8193927..03e11e5 100644 --- a/src/Client.php +++ b/src/Client.php @@ -20,8 +20,6 @@ class Client extends EventEmitter private $stream; private $parser; private $serializer; - private $requests = array(); - private $ending = false; public function __construct(Stream $stream, ParserInterface $parser = null, SerializerInterface $serializer = null) { @@ -48,7 +46,7 @@ public function __construct(Stream $stream, ParserInterface $parser = null, Seri foreach ($models as $data) { try { - $that->handleMessage($data); + $that->emit('message', array($data, $that)); } catch (UnderflowException $error) { $that->emit('error', array($error)); @@ -67,73 +65,13 @@ public function __construct(Stream $stream, ParserInterface $parser = null, Seri $this->serializer = $serializer; } - public function __call($name, $args) + public function send($name, $args) { - $request = new Deferred(); - - if ($this->ending) { - $request->reject(new RuntimeException('Connection closed')); - } else { - $this->stream->write($this->serializer->getRequestMessage($name, $args)); - $this->requests []= $request; - } - - return $request->promise(); - } - - public function handleMessage(ModelInterface $message) - { - $this->emit('message', array($message, $this)); - - if (!$this->requests) { - throw new UnderflowException('Unexpected reply received, no matching request found'); - } - - $request = array_shift($this->requests); - /* @var $request Deferred */ - - if ($message instanceof ErrorReply) { - $request->reject($message); - } else { - $request->resolve($message->getValueNative()); - } - - if ($this->ending && !$this->isBusy()) { - $this->close(); - } - } - - public function isBusy() - { - return !!$this->requests; - } - - /** - * end connection once all pending requests have been replied to - * - * @uses self::close() once all replies have been received - * @see self::close() for closing the connection immediately - */ - public function end() - { - $this->ending = true; - - if (!$this->isBusy()) { - $this->close(); - } + $this->stream->write($this->serializer->getRequestMessage($name, $args)); } public function close() { - $this->ending = true; - $this->stream->close(); - - // reject all remaining requests in the queue - while($this->requests) { - $request = array_shift($this->requests); - /* @var $request Request */ - $request->reject(new RuntimeException('Connection closing')); - } } } diff --git a/src/Factory.php b/src/Factory.php index f4e5054..57105f3 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -43,7 +43,8 @@ public function createClient($target = null) if ($auth !== null) { $promise = $promise->then(function (Client $client) use ($auth) { - return $client->auth($auth)->then( + $api = new ResponseApi($client); + return $api->auth($auth)->then( function () use ($client) { return $client; }, @@ -57,7 +58,8 @@ function ($error) use ($client) { if ($db !== null) { $promise = $promise->then(function (Client $client) use ($db) { - return $client->select($db)->then( + $api = new ResponseApi($client); + return $api->select($db)->then( function () use ($client) { return $client; }, diff --git a/src/ResponseApi.php b/src/ResponseApi.php new file mode 100644 index 0000000..762aab0 --- /dev/null +++ b/src/ResponseApi.php @@ -0,0 +1,95 @@ +client = $client; + + $client->on('message', array($this, 'handleMessage')); + $client->on('close', array($this, 'handleClose')); + } + + public function __call($name, $args) + { + $request = new Deferred(); + + if ($this->ending) { + $request->reject(new RuntimeException('Connection closed')); + } else { + $this->client->send($name, $args); + $this->requests []= $request; + } + + return $request->promise(); + } + + public function handleMessage(ModelInterface $message) + { + if (!$this->requests) { + throw new UnderflowException('Unexpected reply received, no matching request found'); + } + + $request = array_shift($this->requests); + /* @var $request Deferred */ + + if ($message instanceof ErrorReply) { + $request->reject($message); + } else { + $request->resolve($message->getValueNative()); + } + + if ($this->ending && !$this->isBusy()) { + $this->client->close(); + } + } + + public function handleClose() + { + $this->ending = true; + + $this->client->removeListener('message', array($this, 'handleMessage')); + $this->client->removeListener('close', array($this, 'handleClose')); + + // reject all remaining requests in the queue + while($this->requests) { + $request = array_shift($this->requests); + /* @var $request Request */ + $request->reject(new RuntimeException('Connection closing')); + } + + $this->requests = array(); + } + + public function isBusy() + { + return !!$this->requests; + } + + /** + * end connection once all pending requests have been replied to + * + * @uses self::close() once all replies have been received + * @see self::close() for closing the connection immediately + */ + public function end() + { + $this->ending = true; + + if (!$this->isBusy()) { + $this->client->close(); + } + } +} diff --git a/tests/ClientTest.php b/tests/ClientTest.php new file mode 100644 index 0000000..cb07490 --- /dev/null +++ b/tests/ClientTest.php @@ -0,0 +1,79 @@ +stream = $this->getMockBuilder('React\Stream\Stream')->disableOriginalConstructor()->setMethods(array('write', 'close', 'resume', 'pause'))->getMock(); + $this->parser = $this->getMock('Clue\Redis\Protocol\Parser\ParserInterface'); + $this->serializer = $this->getMock('Clue\Redis\Protocol\Serializer\SerializerInterface'); + + $this->client = new Client($this->stream, $this->parser, $this->serializer); + } + + public function testSending() + { + $this->serializer->expects($this->once())->method('getRequestMessage')->with($this->equalTo('ping'))->will($this->returnValue('message')); + $this->stream->expects($this->once())->method('write')->with($this->equalTo('message')); + + $this->client->send('ping', array()); + } + + public function testClosingClientEmitsEvent() + { + //$this->client->on('close', $this->expectCallableOnce()); + + $this->client->close(); + } + + public function testClosingStreamClosesClient() + { + $this->client->on('close', $this->expectCallableOnce()); + + $this->stream->emit('close'); + } + + public function testReceiveParseErrorEmitsErrorEvent() + { + $this->client->on('error', $this->expectCallableOnce()); + //$this->client->on('close', $this->expectCallableOnce()); + + $this->parser->expects($this->once())->method('pushIncoming')->with($this->equalTo('message'))->will($this->throwException(new ParserException())); + $this->stream->emit('data', array('message')); + } + + public function testReceiveMessageEmitsEvent() + { + $this->client->on('message', $this->expectCallableOnce()); + + $this->parser->expects($this->once())->method('pushIncoming')->with($this->equalTo('message'))->will($this->returnValue(array(new IntegerReply(2)))); + $this->stream->emit('data', array('message')); + } + + public function testReceiveThrowMessageEmitsErrorEvent() + { + $this->client->on('message', $this->expectCallableOnce()); + $this->client->on('message', function() { + throw new UnderflowException(); + }); + + $this->client->on('error', $this->expectCallableOnce()); + + $this->parser->expects($this->once())->method('pushIncoming')->with($this->equalTo('message'))->will($this->returnValue(array(new IntegerReply(2)))); + $this->stream->emit('data', array('message')); + } + + public function testDefaultCtor() + { + $client = new Client($this->stream); + } +} diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index aa71767..4d59cc5 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -7,6 +7,7 @@ use Clue\React\Redis\Factory; use Clue\React\Redis\Client; +use Clue\React\Redis\ResponseApi; class FunctionalTest extends TestCase { @@ -25,7 +26,7 @@ public static function setUpBeforeClass() public function testPing() { - $client = $this->createClient(); + $client = $this->createClientApi(); $promise = $client->ping(); $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); @@ -40,10 +41,10 @@ public function testPing() /** * - * @param Client $client + * @param ResponseApi $client * @depends testPing */ - public function testPipeline(Client $client) + public function testPipeline(ResponseApi $client) { $this->assertFalse($client->isBusy()); @@ -61,10 +62,10 @@ public function testPipeline(Client $client) /** * - * @param Client $client + * @param ResponseApi $client * @depends testPipeline */ - public function testInvalidCommand(Client $client) + public function testInvalidCommand(ResponseApi $client) { $client->doesnotexist(1, 2, 3)->then($this->expectCallableNever()); @@ -75,10 +76,10 @@ public function testInvalidCommand(Client $client) /** * - * @param Client $client + * @param ResponseApi $client * @depends testInvalidCommand */ - public function testMultiExecEmpty(Client $client) + public function testMultiExecEmpty(ResponseApi $client) { $client->multi()->then($this->expectCallableOnce('OK')); $client->exec()->then($this->expectCallableOnce(array())); @@ -90,10 +91,10 @@ public function testMultiExecEmpty(Client $client) /** * - * @param Client $client + * @param ResponseApi $client * @depends testMultiExecEmpty */ - public function testMultiExecQueuedExecHasValues(Client $client) + public function testMultiExecQueuedExecHasValues(ResponseApi $client) { $client->multi()->then($this->expectCallableOnce('OK')); $client->set('b', 10)->then($this->expectCallableOnce('QUEUED')); @@ -109,8 +110,8 @@ public function testMultiExecQueuedExecHasValues(Client $client) public function testPubSub() { - $consumer = $this->createClient(); - $producer = $this->createClient(); + $consumer = $this->createClientApi(); + $producer = $this->createClientApi(); $that = $this; @@ -126,36 +127,39 @@ public function testPubSub() public function testClose() { $client = $this->createClient(); + $api = new ResponseApi($client); - $client->get('willBeCanceledAnyway')->then(null, $this->expectCallableOnce()); + $api->get('willBeCanceledAnyway')->then(null, $this->expectCallableOnce()); $client->close(); - $client->get('willBeRejectedRightAway')->then(null, $this->expectCallableOnce()); + $api->get('willBeRejectedRightAway')->then(null, $this->expectCallableOnce()); } public function testInvalidProtocol() { $client = $this->createClientResponse("communication does not conform to protocol\r\n"); + $api = new ResponseApi($client); $client->on('error', $this->expectCallableOnce()); $client->on('close', $this->expectCallableOnce()); - $client->get('willBeRejectedDueToClosing')->then(null, $this->expectCallableOnce()); + $api->get('willBeRejectedDueToClosing')->then(null, $this->expectCallableOnce()); - $this->waitFor($client); + $this->waitFor($api); } public function testInvalidServerRepliesWithDuplicateMessages() { $client = $this->createClientResponse("+OK\r\n-ERR invalid\r\n"); + $api = new ResponseApi($client); $client->on('error', $this->expectCallableOnce()); $client->on('close', $this->expectCallableOnce()); - $client->set('a', 0)->then($this->expectCallableOnce('OK')); + $api->set('a', 0)->then($this->expectCallableOnce('OK')); - $this->waitFor($client); + $this->waitFor($api); } /** @@ -183,6 +187,11 @@ protected function createClient() return $client; } + protected function createClientApi() + { + return new ResponseApi($this->createClient()); + } + protected function createClientResponse($response) { $fp = fopen('php://temp', 'r+'); @@ -201,7 +210,7 @@ protected function createServer($response) } - protected function waitFor(Client $client) + protected function waitFor(ResponseApi $client) { $this->assertTrue($client->isBusy()); diff --git a/tests/ResponseApiTest.php b/tests/ResponseApiTest.php new file mode 100644 index 0000000..9f51849 --- /dev/null +++ b/tests/ResponseApiTest.php @@ -0,0 +1,95 @@ +stream = $this->getMock('React\Stream\Stream'); + //$this->client = new Client($this->stream); + $this->client = $this->getMockBuilder('Clue\React\Redis\Client')->disableOriginalConstructor()->setMethods(array('send', 'close'))->getMock(); + $this->responseApi = new ResponseApi($this->client); + } + + public function testPingPong() + { + $this->client->expects($this->once())->method('send')->with($this->equalTo('ping')); + + $promise = $this->responseApi->ping(); + + $this->client->emit('message', array(new BulkReply('PONG'))); + + $this->expectPromiseResolve($promise); + $promise->then($this->expectCallableOnce('PONG')); + } + + public function testErrorReply() + { + $promise = $this->responseApi->invalid(); + + $err = new ErrorReply('ERR invalid command'); + $this->client->emit('message', array($err)); + + $this->expectPromiseReject($promise); + $promise->then(null, $this->expectCallableOnce($err)); + } + + public function testClosingClientRejectsAllRemainingRequests() + { + $promise = $this->responseApi->ping(); + $this->assertTrue($this->responseApi->isBusy()); + + $this->client->emit('close'); + + $this->expectPromiseReject($promise); + $this->assertFalse($this->responseApi->isBusy()); + } + + public function testClosedClientRejectsAllNewRequests() + { + $this->client->emit('close'); + + $promise = $this->responseApi->ping(); + + $this->expectPromiseReject($promise); + $this->assertFalse($this->responseApi->isBusy()); + } + + public function testEndingNonBusyClosesClient() + { + $this->client->expects($this->once())->method('close'); + $this->responseApi->end(); + } + + public function testEndingBusyClosesClientWhenNotBusyAnymore() + { + // count how often the "close" method has been called + $closed = 0; + $this->client->method('close')->will($this->returnCallback(function() use (&$closed) { + ++$closed; + })); + + $promise = $this->responseApi->ping(); + $this->assertEquals(0, $closed); + + $this->responseApi->end(); + $this->assertEquals(0, $closed); + + $this->client->emit('message', array(new BulkReply('PONG'))); + $this->assertEquals(1, $closed); + } + + public function testReceivingUnexpectedMessageThrowsException() + { + $this->setExpectedException('UnderflowException'); + $this->client->emit('message', array(new BulkReply('PONG'))); + } +} From be586b6f2b81caec776caaca836f806fe60fd442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 26 Jul 2014 01:29:33 +0200 Subject: [PATCH 2/5] Register event handlers only when the API is busy --- src/ResponseApi.php | 21 ++++++++++++--------- tests/FunctionalTest.php | 5 +---- tests/ResponseApiTest.php | 10 ++-------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/ResponseApi.php b/src/ResponseApi.php index 762aab0..844aa4c 100644 --- a/src/ResponseApi.php +++ b/src/ResponseApi.php @@ -17,9 +17,6 @@ class ResponseApi public function __construct(Client $client) { $this->client = $client; - - $client->on('message', array($this, 'handleMessage')); - $client->on('close', array($this, 'handleClose')); } public function __call($name, $args) @@ -29,6 +26,11 @@ public function __call($name, $args) if ($this->ending) { $request->reject(new RuntimeException('Connection closed')); } else { + if (!$this->isBusy()) { + $this->client->on('message', array($this, 'handleMessage')); + $this->client->on('close', array($this, 'handleClose')); + } + $this->client->send($name, $args); $this->requests []= $request; } @@ -38,10 +40,6 @@ public function __call($name, $args) public function handleMessage(ModelInterface $message) { - if (!$this->requests) { - throw new UnderflowException('Unexpected reply received, no matching request found'); - } - $request = array_shift($this->requests); /* @var $request Deferred */ @@ -51,8 +49,13 @@ public function handleMessage(ModelInterface $message) $request->resolve($message->getValueNative()); } - if ($this->ending && !$this->isBusy()) { - $this->client->close(); + if (!$this->isBusy()) { + $this->client->removeListener('message', array($this, 'handleMessage')); + $this->client->removeListener('close', array($this, 'handleClose')); + + if ($this->ending) { + $this->client->close(); + } } } diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index 4d59cc5..7379d3f 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -149,14 +149,11 @@ public function testInvalidProtocol() $this->waitFor($api); } - public function testInvalidServerRepliesWithDuplicateMessages() + public function testAdditionalServerRepliesAreBeingIgnored() { $client = $this->createClientResponse("+OK\r\n-ERR invalid\r\n"); $api = new ResponseApi($client); - $client->on('error', $this->expectCallableOnce()); - $client->on('close', $this->expectCallableOnce()); - $api->set('a', 0)->then($this->expectCallableOnce('OK')); $this->waitFor($api); diff --git a/tests/ResponseApiTest.php b/tests/ResponseApiTest.php index 9f51849..55c2872 100644 --- a/tests/ResponseApiTest.php +++ b/tests/ResponseApiTest.php @@ -55,10 +55,10 @@ public function testClosingClientRejectsAllRemainingRequests() public function testClosedClientRejectsAllNewRequests() { - $this->client->emit('close'); - $promise = $this->responseApi->ping(); + $this->client->emit('close'); + $this->expectPromiseReject($promise); $this->assertFalse($this->responseApi->isBusy()); } @@ -86,10 +86,4 @@ public function testEndingBusyClosesClientWhenNotBusyAnymore() $this->client->emit('message', array(new BulkReply('PONG'))); $this->assertEquals(1, $closed); } - - public function testReceivingUnexpectedMessageThrowsException() - { - $this->setExpectedException('UnderflowException'); - $this->client->emit('message', array(new BulkReply('PONG'))); - } } From 7d62bd57a34f3e70eabdf3e46c93582c2ae0384a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 29 Jul 2014 00:54:36 +0200 Subject: [PATCH 3/5] Rename Client::send() to sendRequest() and add sendMessage() --- src/Client.php | 21 ++++++++++++++++++++- src/ResponseApi.php | 2 +- tests/ClientTest.php | 2 +- tests/ResponseApiTest.php | 4 ++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Client.php b/src/Client.php index 03e11e5..fd2a020 100644 --- a/src/Client.php +++ b/src/Client.php @@ -65,11 +65,30 @@ public function __construct(Stream $stream, ParserInterface $parser = null, Seri $this->serializer = $serializer; } - public function send($name, $args) + /** + * Sends command with given $name and additial $args + * + * @param name $name + * @param array $args + */ + public function sendRequest($name, array $args = array()) { $this->stream->write($this->serializer->getRequestMessage($name, $args)); } + /** + * Sends given message model (request message) + * + * @param ModelInterface $message + */ + public function sendMessage(ModelInterface $message) + { + $this->stream->write($message->getMessageSerialized($this->serializer)); + } + + /** + * Immediately terminate the connection and discard incoming and outgoing buffers + */ public function close() { $this->stream->close(); diff --git a/src/ResponseApi.php b/src/ResponseApi.php index 844aa4c..1b04e72 100644 --- a/src/ResponseApi.php +++ b/src/ResponseApi.php @@ -31,7 +31,7 @@ public function __call($name, $args) $this->client->on('close', array($this, 'handleClose')); } - $this->client->send($name, $args); + $this->client->sendRequest($name, $args); $this->requests []= $request; } diff --git a/tests/ClientTest.php b/tests/ClientTest.php index cb07490..d1a96c7 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -25,7 +25,7 @@ public function testSending() $this->serializer->expects($this->once())->method('getRequestMessage')->with($this->equalTo('ping'))->will($this->returnValue('message')); $this->stream->expects($this->once())->method('write')->with($this->equalTo('message')); - $this->client->send('ping', array()); + $this->client->sendRequest('ping', array()); } public function testClosingClientEmitsEvent() diff --git a/tests/ResponseApiTest.php b/tests/ResponseApiTest.php index 55c2872..9e6c6df 100644 --- a/tests/ResponseApiTest.php +++ b/tests/ResponseApiTest.php @@ -15,13 +15,13 @@ public function setUp() { //$this->stream = $this->getMock('React\Stream\Stream'); //$this->client = new Client($this->stream); - $this->client = $this->getMockBuilder('Clue\React\Redis\Client')->disableOriginalConstructor()->setMethods(array('send', 'close'))->getMock(); + $this->client = $this->getMockBuilder('Clue\React\Redis\Client')->disableOriginalConstructor()->setMethods(array('sendRequest', 'close'))->getMock(); $this->responseApi = new ResponseApi($this->client); } public function testPingPong() { - $this->client->expects($this->once())->method('send')->with($this->equalTo('ping')); + $this->client->expects($this->once())->method('sendRequest')->with($this->equalTo('ping')); $promise = $this->responseApi->ping(); From a14bb1c18025d02066411f163d5af38abf983e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 29 Jul 2014 00:55:29 +0200 Subject: [PATCH 4/5] Update readme example to use new ReponseApi --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 15928c6..5fba797 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,21 @@ local redis server and send some requests: $factory = new Factory($connector); $factory->createClient()->then(function (Client $client) use ($loop) { - $client->SET('greeting', 'Hello world'); - $client->APPEND('greeting', '!'); + $api = new ResponseApi($client); - $client->GET('greeting')->then(function ($greeting) { + $api->set('greeting', 'Hello world'); + $api->append('greeting', '!'); + + $api->get('greeting')->then(function ($greeting) { echo $greeting . PHP_EOL; }); - $client->INCR('invocation')->then(function ($n) { + $api->incr('invocation')->then(function ($n) { echo 'count: ' . $n . PHP_EOL; }); // end connection once all pending requests have been resolved - $client->end(); + $api->end(); }); $loop->run(); From cc901b65a9eed6abc945806135386f02adcec4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 29 Jul 2014 01:07:29 +0200 Subject: [PATCH 5/5] Rename ReponseApi to RequestApi :) --- README.md | 2 +- example/incr.php | 4 ++-- src/Factory.php | 4 ++-- src/{ResponseApi.php => RequestApi.php} | 2 +- tests/FunctionalTest.php | 28 ++++++++++++------------- tests/ResponseApiTest.php | 28 ++++++++++++------------- 6 files changed, 34 insertions(+), 34 deletions(-) rename src/{ResponseApi.php => RequestApi.php} (99%) diff --git a/README.md b/README.md index 5fba797..50eca85 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ local redis server and send some requests: $factory = new Factory($connector); $factory->createClient()->then(function (Client $client) use ($loop) { - $api = new ResponseApi($client); + $api = new RequestApi($client); $api->set('greeting', 'Hello world'); $api->append('greeting', '!'); diff --git a/example/incr.php b/example/incr.php index b2b84e1..b9bea4e 100644 --- a/example/incr.php +++ b/example/incr.php @@ -2,7 +2,7 @@ use Clue\React\Redis\Client; use Clue\React\Redis\Factory; -use Clue\React\Redis\ResponseApi; +use Clue\React\Redis\RequestApi; require __DIR__ . '/../vendor/autoload.php'; @@ -13,7 +13,7 @@ $factory = new Factory($connector); $factory->createClient()->then(function (Client $client) { - $api = new ResponseApi($client); + $api = new RequestApi($client); $api->incr('test'); diff --git a/src/Factory.php b/src/Factory.php index 57105f3..bad5e00 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -43,7 +43,7 @@ public function createClient($target = null) if ($auth !== null) { $promise = $promise->then(function (Client $client) use ($auth) { - $api = new ResponseApi($client); + $api = new RequestApi($client); return $api->auth($auth)->then( function () use ($client) { return $client; @@ -58,7 +58,7 @@ function ($error) use ($client) { if ($db !== null) { $promise = $promise->then(function (Client $client) use ($db) { - $api = new ResponseApi($client); + $api = new RequestApi($client); return $api->select($db)->then( function () use ($client) { return $client; diff --git a/src/ResponseApi.php b/src/RequestApi.php similarity index 99% rename from src/ResponseApi.php rename to src/RequestApi.php index 1b04e72..ba476bd 100644 --- a/src/ResponseApi.php +++ b/src/RequestApi.php @@ -8,7 +8,7 @@ use React\Promise\Deferred; use Clue\Redis\Protocol\Model\ErrorReply; -class ResponseApi +class RequestApi { private $client; private $requests = array(); diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index 7379d3f..95bb22c 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -7,7 +7,7 @@ use Clue\React\Redis\Factory; use Clue\React\Redis\Client; -use Clue\React\Redis\ResponseApi; +use Clue\React\Redis\RequestApi; class FunctionalTest extends TestCase { @@ -41,10 +41,10 @@ public function testPing() /** * - * @param ResponseApi $client + * @param RequestApi $client * @depends testPing */ - public function testPipeline(ResponseApi $client) + public function testPipeline(RequestApi $client) { $this->assertFalse($client->isBusy()); @@ -62,10 +62,10 @@ public function testPipeline(ResponseApi $client) /** * - * @param ResponseApi $client + * @param RequestApi $client * @depends testPipeline */ - public function testInvalidCommand(ResponseApi $client) + public function testInvalidCommand(RequestApi $client) { $client->doesnotexist(1, 2, 3)->then($this->expectCallableNever()); @@ -76,10 +76,10 @@ public function testInvalidCommand(ResponseApi $client) /** * - * @param ResponseApi $client + * @param RequestApi $client * @depends testInvalidCommand */ - public function testMultiExecEmpty(ResponseApi $client) + public function testMultiExecEmpty(RequestApi $client) { $client->multi()->then($this->expectCallableOnce('OK')); $client->exec()->then($this->expectCallableOnce(array())); @@ -91,10 +91,10 @@ public function testMultiExecEmpty(ResponseApi $client) /** * - * @param ResponseApi $client + * @param RequestApi $client * @depends testMultiExecEmpty */ - public function testMultiExecQueuedExecHasValues(ResponseApi $client) + public function testMultiExecQueuedExecHasValues(RequestApi $client) { $client->multi()->then($this->expectCallableOnce('OK')); $client->set('b', 10)->then($this->expectCallableOnce('QUEUED')); @@ -127,7 +127,7 @@ public function testPubSub() public function testClose() { $client = $this->createClient(); - $api = new ResponseApi($client); + $api = new RequestApi($client); $api->get('willBeCanceledAnyway')->then(null, $this->expectCallableOnce()); @@ -139,7 +139,7 @@ public function testClose() public function testInvalidProtocol() { $client = $this->createClientResponse("communication does not conform to protocol\r\n"); - $api = new ResponseApi($client); + $api = new RequestApi($client); $client->on('error', $this->expectCallableOnce()); $client->on('close', $this->expectCallableOnce()); @@ -152,7 +152,7 @@ public function testInvalidProtocol() public function testAdditionalServerRepliesAreBeingIgnored() { $client = $this->createClientResponse("+OK\r\n-ERR invalid\r\n"); - $api = new ResponseApi($client); + $api = new RequestApi($client); $api->set('a', 0)->then($this->expectCallableOnce('OK')); @@ -186,7 +186,7 @@ protected function createClient() protected function createClientApi() { - return new ResponseApi($this->createClient()); + return new RequestApi($this->createClient()); } protected function createClientResponse($response) @@ -207,7 +207,7 @@ protected function createServer($response) } - protected function waitFor(ResponseApi $client) + protected function waitFor(RequestApi $client) { $this->assertTrue($client->isBusy()); diff --git a/tests/ResponseApiTest.php b/tests/ResponseApiTest.php index 9e6c6df..cf400a4 100644 --- a/tests/ResponseApiTest.php +++ b/tests/ResponseApiTest.php @@ -1,29 +1,29 @@ stream = $this->getMock('React\Stream\Stream'); //$this->client = new Client($this->stream); $this->client = $this->getMockBuilder('Clue\React\Redis\Client')->disableOriginalConstructor()->setMethods(array('sendRequest', 'close'))->getMock(); - $this->responseApi = new ResponseApi($this->client); + $this->RequestApi = new RequestApi($this->client); } public function testPingPong() { $this->client->expects($this->once())->method('sendRequest')->with($this->equalTo('ping')); - $promise = $this->responseApi->ping(); + $promise = $this->RequestApi->ping(); $this->client->emit('message', array(new BulkReply('PONG'))); @@ -33,7 +33,7 @@ public function testPingPong() public function testErrorReply() { - $promise = $this->responseApi->invalid(); + $promise = $this->RequestApi->invalid(); $err = new ErrorReply('ERR invalid command'); $this->client->emit('message', array($err)); @@ -44,29 +44,29 @@ public function testErrorReply() public function testClosingClientRejectsAllRemainingRequests() { - $promise = $this->responseApi->ping(); - $this->assertTrue($this->responseApi->isBusy()); + $promise = $this->RequestApi->ping(); + $this->assertTrue($this->RequestApi->isBusy()); $this->client->emit('close'); $this->expectPromiseReject($promise); - $this->assertFalse($this->responseApi->isBusy()); + $this->assertFalse($this->RequestApi->isBusy()); } public function testClosedClientRejectsAllNewRequests() { - $promise = $this->responseApi->ping(); + $promise = $this->RequestApi->ping(); $this->client->emit('close'); $this->expectPromiseReject($promise); - $this->assertFalse($this->responseApi->isBusy()); + $this->assertFalse($this->RequestApi->isBusy()); } public function testEndingNonBusyClosesClient() { $this->client->expects($this->once())->method('close'); - $this->responseApi->end(); + $this->RequestApi->end(); } public function testEndingBusyClosesClientWhenNotBusyAnymore() @@ -77,10 +77,10 @@ public function testEndingBusyClosesClientWhenNotBusyAnymore() ++$closed; })); - $promise = $this->responseApi->ping(); + $promise = $this->RequestApi->ping(); $this->assertEquals(0, $closed); - $this->responseApi->end(); + $this->RequestApi->end(); $this->assertEquals(0, $closed); $this->client->emit('message', array(new BulkReply('PONG')));