24
24
use Laudis \Neo4j \Bolt \BoltConnection ;
25
25
use Laudis \Neo4j \Bolt \BoltConnectionPool ;
26
26
use Laudis \Neo4j \Common \Uri ;
27
+ use Laudis \Neo4j \Contracts \AddressResolverInterface ;
27
28
use Laudis \Neo4j \Contracts \AuthenticateInterface ;
28
29
use Laudis \Neo4j \Contracts \ConnectionInterface ;
29
30
use Laudis \Neo4j \Contracts \ConnectionPoolInterface ;
32
33
use Laudis \Neo4j \Enum \RoutingRoles ;
33
34
use Psr \Http \Message \UriInterface ;
34
35
use function random_int ;
36
+ use RuntimeException ;
37
+ use function sprintf ;
35
38
use function str_starts_with ;
36
39
use function time ;
37
40
@@ -52,13 +55,15 @@ final class Neo4jConnectionPool implements ConnectionPoolInterface
52
55
private static array $ routingCache = [];
53
56
/** @psalm-readonly */
54
57
private BoltConnectionPool $ pool ;
58
+ private AddressResolverInterface $ resolver ;
55
59
56
60
/**
57
61
* @psalm-mutation-free
58
62
*/
59
- public function __construct (BoltConnectionPool $ pool )
63
+ public function __construct (BoltConnectionPool $ pool, AddressResolverInterface $ resolver )
60
64
{
61
65
$ this ->pool = $ pool ;
66
+ $ this ->resolver = $ resolver ;
62
67
}
63
68
64
69
/**
@@ -73,10 +78,20 @@ public function acquire(
73
78
74
79
$ table = self ::$ routingCache [$ key ] ?? null ;
75
80
if ($ table === null || $ table ->getTtl () < time ()) {
76
- $ connection = $ this ->pool ->acquire ($ uri , $ authenticate , $ config );
77
- $ table = $ this ->routingTable ($ connection , $ config );
78
- self ::$ routingCache [$ key ] = $ table ;
79
- $ connection ->close ();
81
+ $ addresses = $ this ->resolver ->getAddresses ($ uri ->getHost ());
82
+ $ triedAddresses = [];
83
+ foreach ($ addresses as $ address ) {
84
+ $ triedAddresses [] = $ address ;
85
+ if ($ this ->pool ->canConnect ($ uri ->withHost ($ address ), $ authenticate )) {
86
+ $ connection = $ this ->pool ->acquire ($ uri ->withHost ($ address ), $ authenticate , $ config );
87
+ $ table = $ this ->routingTable ($ connection , $ config );
88
+ self ::$ routingCache [$ key ] = $ table ;
89
+ $ connection ->close ();
90
+ break ;
91
+ }
92
+ }
93
+
94
+ throw new RuntimeException (sprintf ('Cannot connect to address: "%s". Addresses tried: "%s" ' , $ uri ->getHost (), implode ('", " ' , $ triedAddresses )));
80
95
}
81
96
82
97
$ server = $ this ->getNextServer ($ table , $ config ->getAccessMode ()) ?? $ uri ;
0 commit comments