1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<?php
namespace ConnectionManager\Extra\Multiple;
use React\Socket\ConnectorInterface;
use React\Promise;
use UnderflowException;
use React\Promise\CancellablePromiseInterface;
class ConnectionManagerConsecutive implements ConnectorInterface
{
protected $managers;
/**
*
* @param ConnectorInterface[] $managers
*/
public function __construct(array $managers)
{
if (!$managers) {
throw new \InvalidArgumentException('List of connectors must not be empty');
}
$this->managers = $managers;
}
public function connect($uri)
{
return $this->tryConnection($this->managers, $uri);
}
/**
*
* @param ConnectorInterface[] $managers
* @param string $uri
* @return Promise
* @internal
*/
public function tryConnection(array $managers, $uri)
{
return new Promise\Promise(function ($resolve, $reject) use (&$managers, &$pending, $uri) {
$try = function () use (&$try, &$managers, $uri, $resolve, $reject, &$pending) {
if (!$managers) {
return $reject(new UnderflowException('No more managers to try to connect through'));
}
$manager = array_shift($managers);
$pending = $manager->connect($uri);
$pending->then($resolve, $try);
};
$try();
}, function ($_, $reject) use (&$managers, &$pending) {
// stop retrying, reject results and cancel pending attempt
$managers = array();
$reject(new \RuntimeException('Cancelled'));
if ($pending instanceof CancellablePromiseInterface) {
$pending->cancel();
}
});
}
}
|