Skip to content

Commit

Permalink
Simplify usage by supporting new default loop
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonFrings committed Jul 28, 2021
1 parent c4a8cbb commit bd94553
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 54 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ Once [installed](#install), you can use the following code to connect to your
local Redis server and send some requests:

```php
$loop = React\EventLoop\Factory::create();
$factory = new Clue\React\Redis\Factory($loop);
$factory = new Clue\React\Redis\Factory();

$client = $factory->createLazyClient('localhost');
$client->set('greeting', 'Hello world');
Expand All @@ -78,8 +77,6 @@ $client->incr('invocation')->then(function ($n) {

// end connection once all pending requests have been resolved
$client->end();

$loop->run();
```

See also the [examples](examples).
Expand All @@ -89,18 +86,22 @@ See also the [examples](examples).
### Factory

The `Factory` is responsible for creating your [`Client`](#client) instance.
It also registers everything with the main [`EventLoop`](https://github.com/reactphp/event-loop#usage).

```php
$loop = \React\EventLoop\Factory::create();
$factory = new \Clue\React\Redis\Factory($loop);
$factory = new Clue\React\Redis\Factory();
```

This class takes an optional `LoopInterface|null $loop` parameter that can be used to
pass the event loop instance to use for this object. You can use a `null` value
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
This value SHOULD NOT be given unless you're sure you want to explicitly use a
given event loop instance.

If you need custom DNS, proxy or TLS settings, you can explicitly pass a
custom instance of the [`ConnectorInterface`](https://github.com/reactphp/socket#connectorinterface):

```php
$connector = new \React\Socket\Connector($loop, array(
$connector = new React\Socket\Connector(null, array(
'dns' => '127.0.0.1',
'tcp' => array(
'bindto' => '192.168.10.1:0'
Expand All @@ -111,7 +112,7 @@ $connector = new \React\Socket\Connector($loop, array(
)
));

$factory = new Factory($loop, $connector);
$factory = new Clue\React\Redis\Factory(null, $connector);
```

#### createClient()
Expand Down Expand Up @@ -146,7 +147,7 @@ connection attempt and/or Redis authentication.
```php
$promise = $factory->createClient($redisUri);

$loop->addTimer(3.0, function () use ($promise) {
Loop::addTimer(3.0, function () use ($promise) {
$promise->cancel();
});
```
Expand Down Expand Up @@ -466,7 +467,7 @@ respectively:
```php
$client->subscribe('user');

$loop->addTimer(60.0, function () use ($client) {
Loop::addTimer(60.0, function () use ($client) {
$client->unsubscribe('user');
});
```
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
"php": ">=5.3",
"clue/redis-protocol": "0.3.*",
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"react/event-loop": "^1.0 || ^0.5",
"react/event-loop": "^1.2",
"react/promise": "^2.0 || ^1.1",
"react/promise-timer": "^1.5",
"react/socket": "^1.1"
"react/socket": "^1.8"
},
"require-dev": {
"clue/block-react": "^1.1",
Expand Down
16 changes: 7 additions & 9 deletions examples/cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

use Clue\React\Redis\Client;
use Clue\React\Redis\Factory;
use React\EventLoop\Loop;
use React\Promise\PromiseInterface;

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);
$factory = new Factory();

echo '# connecting to redis...' . PHP_EOL;

$factory->createClient('localhost')->then(function (Client $client) use ($loop) {
$factory->createClient('localhost')->then(function (Client $client) {
echo '# connected! Entering interactive mode, hit CTRL-D to quit' . PHP_EOL;

$loop->addReadStream(STDIN, function () use ($client, $loop) {
Loop::addReadStream(STDIN, function () use ($client) {
$line = fgets(STDIN);
if ($line === false || $line === '') {
echo '# CTRL-D -> Ending connection...' . PHP_EOL;
$loop->removeReadStream(STDIN);
Loop::removeReadStream(STDIN);
return $client->end();
}

Expand All @@ -43,10 +43,10 @@
});
});

$client->on('close', function() use ($loop) {
$client->on('close', function() {
echo '## DISCONNECTED' . PHP_EOL;

$loop->removeReadStream(STDIN);
Loop::removeReadStream(STDIN);
});
}, function (Exception $error) {
echo 'CONNECTION ERROR: ' . $error->getMessage() . PHP_EOL;
Expand All @@ -55,5 +55,3 @@
}
exit(1);
});

$loop->run();
5 changes: 1 addition & 4 deletions examples/incr.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);
$factory = new Factory();

$client = $factory->createLazyClient('localhost');
$client->incr('test');
Expand All @@ -21,5 +20,3 @@
});

$client->end();

$loop->run();
5 changes: 1 addition & 4 deletions examples/publish.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);
$factory = new Factory();

$channel = isset($argv[1]) ? $argv[1] : 'channel';
$message = isset($argv[2]) ? $argv[2] : 'message';
Expand All @@ -22,5 +21,3 @@
});

$client->end();

$loop->run();
14 changes: 6 additions & 8 deletions examples/subscribe.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

use Clue\React\Redis\Factory;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);
$factory = new Factory();

$channel = isset($argv[1]) ? $argv[1] : 'channel';

Expand All @@ -22,17 +22,15 @@
});

// automatically re-subscribe to channel on connection issues
$client->on('unsubscribe', function ($channel) use ($client, $loop) {
$client->on('unsubscribe', function ($channel) use ($client) {
echo 'Unsubscribed from ' . $channel . PHP_EOL;

$loop->addPeriodicTimer(2.0, function ($timer) use ($client, $channel, $loop){
$client->subscribe($channel)->then(function () use ($timer, $loop) {
Loop::addPeriodicTimer(2.0, function ($timer) use ($client, $channel){
$client->subscribe($channel)->then(function () use ($timer) {
echo 'Now subscribed again' . PHP_EOL;
$loop->cancelTimer($timer);
Loop::cancelTimer($timer);
}, function (Exception $e) {
echo 'Unable to subscribe again: ' . $e->getMessage() . PHP_EOL;
});
});
});

$loop->run();
29 changes: 13 additions & 16 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Clue\React\Redis;

use Clue\Redis\Protocol\Factory as ProtocolFactory;
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use React\Promise\Deferred;
use React\Promise\Timer\TimeoutException;
Expand All @@ -13,29 +14,25 @@

class Factory
{
/** @var LoopInterface */
private $loop;

/** @var ConnectorInterface */
private $connector;

/** @var ProtocolFactory */
private $protocol;

/**
* @param LoopInterface $loop
* @param ConnectorInterface|null $connector [optional] Connector to use.
* Should be `null` in order to use default Connector.
* @param ProtocolFactory|null $protocol
* @param ?LoopInterface $loop
* @param ?ConnectorInterface $connector
* @param ?ProtocolFactory $protocol
*/
public function __construct(LoopInterface $loop, ConnectorInterface $connector = null, ProtocolFactory $protocol = null)
public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null, ProtocolFactory $protocol = null)
{
if ($connector === null) {
$connector = new Connector($loop);
}

if ($protocol === null) {
$protocol = new ProtocolFactory();
}

$this->loop = $loop;
$this->connector = $connector;
$this->protocol = $protocol;
$this->loop = $loop ?: Loop::get();
$this->connector = $connector ?: new Connector($this->loop);
$this->protocol = $protocol ?: new ProtocolFactory();
}

/**
Expand Down
11 changes: 11 additions & 0 deletions tests/FactoryLazyClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ public function setUpFactory()
$this->factory = new Factory($this->loop, $this->connector);
}

public function testConstructWithoutLoopAssignsLoopAutomatically()
{
$factory = new Factory();

$ref = new \ReflectionProperty($factory, 'loop');
$ref->setAccessible(true);
$loop = $ref->getValue($factory);

$this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
}

public function testWillConnectWithDefaultPort()
{
$this->connector->expects($this->never())->method('connect')->with('redis.example.com:6379')->willReturn(Promise\reject(new \RuntimeException()));
Expand Down
11 changes: 11 additions & 0 deletions tests/FactoryStreamingClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ public function setUpFactory()
$this->factory = new Factory($this->loop, $this->connector);
}

public function testConstructWithoutLoopAssignsLoopAutomatically()
{
$factory = new Factory();

$ref = new \ReflectionProperty($factory, 'loop');
$ref->setAccessible(true);
$loop = $ref->getValue($factory);

$this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
}

/**
* @doesNotPerformAssertions
*/
Expand Down

0 comments on commit bd94553

Please sign in to comment.