Skip to content

Commit 26c2d48

Browse files
committed
Remove optional $loop constructor argument, always use default loop
1 parent e9de03f commit 26c2d48

File tree

6 files changed

+148
-87
lines changed

6 files changed

+148
-87
lines changed

README.md

-6
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,6 @@ $connector = new React\Socket\Connector([
413413
$redis = new Clue\React\Redis\RedisClient('localhost', $connector);
414414
```
415415

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

424418
The `__call(string $name, string[] $args): PromiseInterface<mixed>` method can be used to

src/Io/Factory.php

+5-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Clue\Redis\Protocol\Factory as ProtocolFactory;
66
use React\EventLoop\Loop;
7-
use React\EventLoop\LoopInterface;
87
use React\Promise\Deferred;
98
use React\Promise\Promise;
109
use React\Promise\PromiseInterface;
@@ -18,24 +17,19 @@
1817
*/
1918
class Factory
2019
{
21-
/** @var LoopInterface */
22-
private $loop;
23-
2420
/** @var ConnectorInterface */
2521
private $connector;
2622

2723
/** @var ProtocolFactory */
2824
private $protocol;
2925

3026
/**
31-
* @param ?LoopInterface $loop
3227
* @param ?ConnectorInterface $connector
3328
* @param ?ProtocolFactory $protocol
3429
*/
35-
public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null, ProtocolFactory $protocol = null)
30+
public function __construct(ConnectorInterface $connector = null, ProtocolFactory $protocol = null)
3631
{
37-
$this->loop = $loop ?: Loop::get();
38-
$this->connector = $connector ?: new Connector([], $this->loop);
32+
$this->connector = $connector ?: new Connector();
3933
$this->protocol = $protocol ?: new ProtocolFactory();
4034
}
4135

@@ -182,13 +176,13 @@ function (\Exception $e) use ($redis, $uri) {
182176
$timer = null;
183177
$promise = $promise->then(function (StreamingClient $v) use (&$timer, $resolve): void {
184178
if ($timer) {
185-
$this->loop->cancelTimer($timer);
179+
Loop::cancelTimer($timer);
186180
}
187181
$timer = false;
188182
$resolve($v);
189183
}, function (\Throwable $e) use (&$timer, $reject): void {
190184
if ($timer) {
191-
$this->loop->cancelTimer($timer);
185+
Loop::cancelTimer($timer);
192186
}
193187
$timer = false;
194188
$reject($e);
@@ -200,7 +194,7 @@ function (\Exception $e) use ($redis, $uri) {
200194
}
201195

202196
// start timeout timer which will cancel the pending promise
203-
$timer = $this->loop->addTimer($timeout, function () use ($timeout, &$promise, $reject, $uri): void {
197+
$timer = Loop::addTimer($timeout, function () use ($timeout, &$promise, $reject, $uri): void {
204198
$reject(new \RuntimeException(
205199
'Connection to ' . $uri . ' timed out after ' . $timeout . ' seconds (ETIMEDOUT)',
206200
\defined('SOCKET_ETIMEDOUT') ? \SOCKET_ETIMEDOUT : 110

src/RedisClient.php

+6-16
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use Clue\React\Redis\Io\StreamingClient;
77
use Evenement\EventEmitter;
88
use React\EventLoop\Loop;
9-
use React\EventLoop\LoopInterface;
109
use React\Promise\PromiseInterface;
1110
use React\Socket\ConnectorInterface;
1211
use React\Stream\Util;
@@ -40,9 +39,6 @@ class RedisClient extends EventEmitter
4039
/** @var ?PromiseInterface<StreamingClient> */
4140
private $promise = null;
4241

43-
/** @var LoopInterface */
44-
private $loop;
45-
4642
/** @var float */
4743
private $idlePeriod = 0.001;
4844

@@ -58,12 +54,7 @@ class RedisClient extends EventEmitter
5854
/** @var array<string,bool> */
5955
private $psubscribed = [];
6056

61-
/**
62-
* @param string $url
63-
* @param ?ConnectorInterface $connector
64-
* @param ?LoopInterface $loop
65-
*/
66-
public function __construct($url, ConnectorInterface $connector = null, LoopInterface $loop = null)
57+
public function __construct(string $url, ConnectorInterface $connector = null)
6758
{
6859
$args = [];
6960
\parse_str((string) \parse_url($url, \PHP_URL_QUERY), $args);
@@ -72,8 +63,7 @@ public function __construct($url, ConnectorInterface $connector = null, LoopInte
7263
}
7364

7465
$this->target = $url;
75-
$this->loop = $loop ?: Loop::get();
76-
$this->factory = new Factory($this->loop, $connector);
66+
$this->factory = new Factory($connector);
7767
}
7868

7969
/**
@@ -102,7 +92,7 @@ private function client(): PromiseInterface
10292
$this->subscribed = $this->psubscribed = [];
10393

10494
if ($this->idleTimer !== null) {
105-
$this->loop->cancelTimer($this->idleTimer);
95+
Loop::cancelTimer($this->idleTimer);
10696
$this->idleTimer = null;
10797
}
10898
});
@@ -235,7 +225,7 @@ public function close(): void
235225
}
236226

237227
if ($this->idleTimer !== null) {
238-
$this->loop->cancelTimer($this->idleTimer);
228+
Loop::cancelTimer($this->idleTimer);
239229
$this->idleTimer = null;
240230
}
241231

@@ -248,7 +238,7 @@ private function awake(): void
248238
++$this->pending;
249239

250240
if ($this->idleTimer !== null) {
251-
$this->loop->cancelTimer($this->idleTimer);
241+
Loop::cancelTimer($this->idleTimer);
252242
$this->idleTimer = null;
253243
}
254244
}
@@ -258,7 +248,7 @@ private function idle(): void
258248
--$this->pending;
259249

260250
if ($this->pending < 1 && $this->idlePeriod >= 0 && !$this->subscribed && !$this->psubscribed && $this->promise !== null) {
261-
$this->idleTimer = $this->loop->addTimer($this->idlePeriod, function () {
251+
$this->idleTimer = Loop::addTimer($this->idlePeriod, function () {
262252
assert($this->promise instanceof PromiseInterface);
263253
$this->promise->then(function (StreamingClient $redis) {
264254
$redis->close();

tests/FunctionalTest.php

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
class FunctionalTest extends TestCase
1212
{
13-
1413
/** @var string */
1514
private $uri;
1615

tests/Io/FactoryStreamingClientTest.php

+74-25
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Clue\React\Redis\Io\StreamingClient;
77
use Clue\Tests\React\Redis\TestCase;
88
use PHPUnit\Framework\MockObject\MockObject;
9+
use React\EventLoop\Loop;
910
use React\EventLoop\LoopInterface;
1011
use React\EventLoop\TimerInterface;
1112
use React\Promise\Deferred;
@@ -16,43 +17,39 @@
1617

1718
class FactoryStreamingClientTest extends TestCase
1819
{
19-
/** @var MockObject */
20-
private $loop;
21-
2220
/** @var MockObject */
2321
private $connector;
2422

2523
/** @var Factory */
2624
private $factory;
2725

28-
public function setUp(): void
29-
{
30-
$this->loop = $this->createMock(LoopInterface::class);
31-
$this->connector = $this->createMock(ConnectorInterface::class);
26+
/** @var LoopInterface */
27+
public static $loop;
3228

33-
assert($this->loop instanceof LoopInterface);
34-
assert($this->connector instanceof ConnectorInterface);
35-
$this->factory = new Factory($this->loop, $this->connector);
29+
public static function setUpBeforeClass(): void
30+
{
31+
self::$loop = Loop::get();
3632
}
3733

38-
public function testConstructWithoutLoopAssignsLoopAutomatically(): void
34+
public static function tearDownAfterClass(): void
3935
{
40-
$factory = new Factory();
36+
Loop::set(self::$loop);
37+
}
4138

42-
$ref = new \ReflectionProperty($factory, 'loop');
43-
$ref->setAccessible(true);
44-
$loop = $ref->getValue($factory);
39+
public function setUp(): void
40+
{
41+
$this->connector = $this->createMock(ConnectorInterface::class);
4542

46-
$this->assertInstanceOf(LoopInterface::class, $loop);
43+
assert($this->connector instanceof ConnectorInterface);
44+
$this->factory = new Factory($this->connector);
4745
}
4846

4947
/**
5048
* @doesNotPerformAssertions
5149
*/
5250
public function testCtor(): void
5351
{
54-
assert($this->loop instanceof LoopInterface);
55-
$this->factory = new Factory($this->loop);
52+
$this->factory = new Factory();
5653
}
5754

5855
public function testWillConnectWithDefaultPort(): void
@@ -87,6 +84,10 @@ public function testWillWriteSelectCommandIfTargetContainsPath(): void
8784
$stream = $this->createMock(ConnectionInterface::class);
8885
$stream->expects($this->once())->method('write')->with("*2\r\n$6\r\nselect\r\n$4\r\ndemo\r\n");
8986

87+
$loop = $this->createMock(LoopInterface::class);
88+
$loop->expects($this->once())->method('addTimer');
89+
Loop::set($loop);
90+
9091
$this->connector->expects($this->once())->method('connect')->willReturn(resolve($stream));
9192
$this->factory->createClient('redis://127.0.0.1/demo');
9293
}
@@ -96,6 +97,10 @@ public function testWillWriteSelectCommandIfTargetContainsDbQueryParameter(): vo
9697
$stream = $this->createMock(ConnectionInterface::class);
9798
$stream->expects($this->once())->method('write')->with("*2\r\n$6\r\nselect\r\n$1\r\n4\r\n");
9899

100+
$loop = $this->createMock(LoopInterface::class);
101+
$loop->expects($this->once())->method('addTimer');
102+
Loop::set($loop);
103+
99104
$this->connector->expects($this->once())->method('connect')->willReturn(resolve($stream));
100105
$this->factory->createClient('redis://127.0.0.1?db=4');
101106
}
@@ -105,6 +110,10 @@ public function testWillWriteAuthCommandIfRedisUriContainsUserInfo(): void
105110
$stream = $this->createMock(ConnectionInterface::class);
106111
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
107112

113+
$loop = $this->createMock(LoopInterface::class);
114+
$loop->expects($this->once())->method('addTimer');
115+
Loop::set($loop);
116+
108117
$this->connector->expects($this->once())->method('connect')->with('example.com:6379')->willReturn(resolve($stream));
109118
$this->factory->createClient('redis://hello:[email protected]');
110119
}
@@ -114,6 +123,10 @@ public function testWillWriteAuthCommandIfRedisUriContainsEncodedUserInfo(): voi
114123
$stream = $this->createMock(ConnectionInterface::class);
115124
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nh@llo\r\n");
116125

126+
$loop = $this->createMock(LoopInterface::class);
127+
$loop->expects($this->once())->method('addTimer');
128+
Loop::set($loop);
129+
117130
$this->connector->expects($this->once())->method('connect')->with('example.com:6379')->willReturn(resolve($stream));
118131
$this->factory->createClient('redis://:h%[email protected]');
119132
}
@@ -123,6 +136,10 @@ public function testWillWriteAuthCommandIfTargetContainsPasswordQueryParameter()
123136
$stream = $this->createMock(ConnectionInterface::class);
124137
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$6\r\nsecret\r\n");
125138

139+
$loop = $this->createMock(LoopInterface::class);
140+
$loop->expects($this->once())->method('addTimer');
141+
Loop::set($loop);
142+
126143
$this->connector->expects($this->once())->method('connect')->with('example.com:6379')->willReturn(resolve($stream));
127144
$this->factory->createClient('redis://example.com?password=secret');
128145
}
@@ -132,6 +149,10 @@ public function testWillWriteAuthCommandIfTargetContainsEncodedPasswordQueryPara
132149
$stream = $this->createMock(ConnectionInterface::class);
133150
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nh@llo\r\n");
134151

152+
$loop = $this->createMock(LoopInterface::class);
153+
$loop->expects($this->once())->method('addTimer');
154+
Loop::set($loop);
155+
135156
$this->connector->expects($this->once())->method('connect')->with('example.com:6379')->willReturn(resolve($stream));
136157
$this->factory->createClient('redis://example.com?password=h%40llo');
137158
}
@@ -141,6 +162,10 @@ public function testWillWriteAuthCommandIfRedissUriContainsUserInfo(): void
141162
$stream = $this->createMock(ConnectionInterface::class);
142163
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
143164

165+
$loop = $this->createMock(LoopInterface::class);
166+
$loop->expects($this->once())->method('addTimer');
167+
Loop::set($loop);
168+
144169
$this->connector->expects($this->once())->method('connect')->with('tls://example.com:6379')->willReturn(resolve($stream));
145170
$this->factory->createClient('rediss://hello:[email protected]');
146171
}
@@ -150,6 +175,10 @@ public function testWillWriteAuthCommandIfRedisUnixUriContainsPasswordQueryParam
150175
$stream = $this->createMock(ConnectionInterface::class);
151176
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
152177

178+
$loop = $this->createMock(LoopInterface::class);
179+
$loop->expects($this->once())->method('addTimer');
180+
Loop::set($loop);
181+
153182
$this->connector->expects($this->once())->method('connect')->with('unix:///tmp/redis.sock')->willReturn(resolve($stream));
154183
$this->factory->createClient('redis+unix:///tmp/redis.sock?password=world');
155184
}
@@ -168,6 +197,10 @@ public function testWillWriteAuthCommandIfRedisUnixUriContainsUserInfo(): void
168197
$stream = $this->createMock(ConnectionInterface::class);
169198
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
170199

200+
$loop = $this->createMock(LoopInterface::class);
201+
$loop->expects($this->once())->method('addTimer');
202+
Loop::set($loop);
203+
171204
$this->connector->expects($this->once())->method('connect')->with('unix:///tmp/redis.sock')->willReturn(resolve($stream));
172205
$this->factory->createClient('redis+unix://hello:world@/tmp/redis.sock');
173206
}
@@ -275,6 +308,10 @@ public function testWillWriteSelectCommandIfRedisUnixUriContainsDbQueryParameter
275308
$stream = $this->createMock(ConnectionInterface::class);
276309
$stream->expects($this->once())->method('write')->with("*2\r\n$6\r\nselect\r\n$4\r\ndemo\r\n");
277310

311+
$loop = $this->createMock(LoopInterface::class);
312+
$loop->expects($this->once())->method('addTimer');
313+
Loop::set($loop);
314+
278315
$this->connector->expects($this->once())->method('connect')->with('unix:///tmp/redis.sock')->willReturn(resolve($stream));
279316
$this->factory->createClient('redis+unix:///tmp/redis.sock?db=demo');
280317
}
@@ -584,8 +621,11 @@ public function testCancelWillCloseConnectionWhenConnectionWaitsForSelect(): voi
584621

585622
public function testCreateClientWithTimeoutParameterWillStartTimerAndRejectOnExplicitTimeout(): void
586623
{
624+
$loop = $this->createMock(LoopInterface::class);
625+
Loop::set($loop);
626+
587627
$timeout = null;
588-
$this->loop->expects($this->once())->method('addTimer')->with(0, $this->callback(function ($cb) use (&$timeout) {
628+
$loop->expects($this->once())->method('addTimer')->with(0, $this->callback(function ($cb) use (&$timeout) {
589629
$timeout = $cb;
590630
return true;
591631
}));
@@ -613,7 +653,10 @@ public function testCreateClientWithTimeoutParameterWillStartTimerAndRejectOnExp
613653

614654
public function testCreateClientWithNegativeTimeoutParameterWillNotStartTimer(): void
615655
{
616-
$this->loop->expects($this->never())->method('addTimer');
656+
$loop = $this->createMock(LoopInterface::class);
657+
Loop::set($loop);
658+
659+
$loop->expects($this->never())->method('addTimer');
617660

618661
$deferred = new Deferred();
619662
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:2')->willReturn($deferred->promise());
@@ -623,7 +666,9 @@ public function testCreateClientWithNegativeTimeoutParameterWillNotStartTimer():
623666

624667
public function testCreateClientWithoutTimeoutParameterWillStartTimerWithDefaultTimeoutFromIni(): void
625668
{
626-
$this->loop->expects($this->once())->method('addTimer')->with(42, $this->anything());
669+
$loop = $this->createMock(LoopInterface::class);
670+
$loop->expects($this->once())->method('addTimer')->with(42, $this->anything());
671+
Loop::set($loop);
627672

628673
$deferred = new Deferred();
629674
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:2')->willReturn($deferred->promise());
@@ -637,9 +682,11 @@ public function testCreateClientWithoutTimeoutParameterWillStartTimerWithDefault
637682

638683
public function testCreateClientWillCancelTimerWhenConnectionResolves(): void
639684
{
685+
$loop = $this->createMock(LoopInterface::class);
640686
$timer = $this->createMock(TimerInterface::class);
641-
$this->loop->expects($this->once())->method('addTimer')->willReturn($timer);
642-
$this->loop->expects($this->once())->method('cancelTimer')->with($timer);
687+
$loop->expects($this->once())->method('addTimer')->willReturn($timer);
688+
$loop->expects($this->once())->method('cancelTimer')->with($timer);
689+
Loop::set($loop);
643690

644691
$deferred = new Deferred();
645692
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:6379')->willReturn($deferred->promise());
@@ -652,9 +699,11 @@ public function testCreateClientWillCancelTimerWhenConnectionResolves(): void
652699

653700
public function testCreateClientWillCancelTimerWhenConnectionRejects(): void
654701
{
702+
$loop = $this->createMock(LoopInterface::class);
655703
$timer = $this->createMock(TimerInterface::class);
656-
$this->loop->expects($this->once())->method('addTimer')->willReturn($timer);
657-
$this->loop->expects($this->once())->method('cancelTimer')->with($timer);
704+
$loop->expects($this->once())->method('addTimer')->willReturn($timer);
705+
$loop->expects($this->once())->method('cancelTimer')->with($timer);
706+
Loop::set($loop);
658707

659708
$deferred = new Deferred();
660709
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:6379')->willReturn($deferred->promise());

0 commit comments

Comments
 (0)