25
25
use Laudis \Neo4j \Contracts \ConnectionInterface ;
26
26
use Laudis \Neo4j \Contracts \ConnectionPoolInterface ;
27
27
use Laudis \Neo4j \Databags \DatabaseInfo ;
28
+ use Laudis \Neo4j \Databags \DriverConfiguration ;
28
29
use Laudis \Neo4j \Databags \SessionConfiguration ;
29
30
use Laudis \Neo4j \Enum \ConnectionProtocol ;
30
31
use Laudis \Neo4j \Neo4j \RoutingTable ;
39
40
*/
40
41
final class BoltConnectionPool implements ConnectionPoolInterface
41
42
{
42
- /** @var array<string, list<ConnectionInterface<Bolt> >> */
43
+ /** @var array<string, list<BoltConnection >> */
43
44
private static array $ connectionCache = [];
45
+ private DriverConfiguration $ driverConfig ;
46
+
47
+ public function __construct (DriverConfiguration $ driverConfig )
48
+ {
49
+ $ this ->driverConfig = $ driverConfig ;
50
+ }
44
51
45
52
/**
46
53
* @throws Exception
@@ -60,8 +67,20 @@ public function acquire(
60
67
self ::$ connectionCache [$ key ] = [];
61
68
}
62
69
63
- foreach (self ::$ connectionCache [$ key ] as $ connection ) {
70
+ foreach (self ::$ connectionCache [$ key ] as $ i => $ connection ) {
64
71
if (!$ connection ->isOpen ()) {
72
+ $ sslConfig = $ connection ->getDriverConfiguration ()->getSslConfiguration ();
73
+ $ newSslConfig = $ this ->driverConfig ->getSslConfiguration ();
74
+ if ($ sslConfig ->getMode () !== $ newSslConfig ->getMode () ||
75
+ $ sslConfig ->isVerifyPeer () === $ newSslConfig ->isVerifyPeer ()
76
+ ) {
77
+ $ connection = $ this ->openConnection ($ connectingTo , $ socketTimeout , $ uri , $ table , $ authenticate , $ userAgent , $ config );
78
+
79
+ /** @psalm-suppress PropertyTypeCoercion */
80
+ self ::$ connectionCache [$ key ][$ i ] = $ connection ;
81
+
82
+ return $ connection ;
83
+ }
65
84
$ connection ->open ();
66
85
67
86
$ authenticate ->authenticateBolt ($ connection ->getImplementation (), $ connectingTo , $ userAgent );
@@ -70,52 +89,7 @@ public function acquire(
70
89
}
71
90
}
72
91
73
- $ socket = new StreamSocket ($ connectingTo ->getHost (), $ connectingTo ->getPort () ?? 7687 , $ socketTimeout );
74
-
75
- $ this ->configureSsl ($ uri , $ connectingTo , $ socket , $ table );
76
-
77
- $ bolt = new Bolt ($ socket );
78
- $ authenticate ->authenticateBolt ($ bolt , $ connectingTo , $ userAgent );
79
-
80
- // We create a weak reference to optimise the socket usage. This way the connection can reuse the bolt variable
81
- // the first time it tries to connect. Only when this function is finished and the returned connection is closed
82
- // will the reference return null, prompting the need to reopen and recreate the bolt object on the same socket.
83
- $ originalBolt = WeakReference::create ($ bolt );
84
-
85
- /**
86
- * @var array{'name': 0, 'version': 1, 'edition': 2}
87
- * @psalm-suppress all
88
- */
89
- $ fields = array_flip ($ bolt ->run (<<<'CYPHER'
90
- CALL dbms.components()
91
- YIELD name, versions, edition
92
- UNWIND versions AS version
93
- RETURN name, version, edition
94
- CYPHER
95
- )['fields ' ]);
96
-
97
- /** @var array{0: array{0: string, 1: string, 2: string}} $results */
98
- $ results = $ bolt ->pullAll ();
99
-
100
- $ connection = new BoltConnection (
101
- $ results [0 ][$ fields ['name ' ]].'- ' .$ results [0 ][$ fields ['edition ' ]].'/ ' .$ results [0 ][$ fields ['version ' ]],
102
- $ connectingTo ,
103
- $ results [0 ][$ fields ['version ' ]],
104
- ConnectionProtocol::determineBoltVersion ($ bolt ),
105
- $ config ->getAccessMode (),
106
- new DatabaseInfo ($ config ->getDatabase ()),
107
- static function () use ($ socket , $ authenticate , $ connectingTo , $ userAgent , $ originalBolt ) {
108
- $ bolt = $ originalBolt ->get ();
109
- if ($ bolt === null ) {
110
- $ bolt = new Bolt ($ socket );
111
- $ authenticate ->authenticateBolt ($ bolt , $ connectingTo , $ userAgent );
112
- }
113
-
114
- return $ bolt ;
115
- }
116
- );
117
-
118
- $ connection ->open ();
92
+ $ connection = $ this ->openConnection ($ connectingTo , $ socketTimeout , $ uri , $ table , $ authenticate , $ userAgent , $ config );
119
93
120
94
self ::$ connectionCache [$ key ][] = $ connection ;
121
95
@@ -174,4 +148,64 @@ public function canConnect(UriInterface $uri, AuthenticateInterface $authenticat
174
148
175
149
return true ;
176
150
}
151
+
152
+ private function openConnection (
153
+ UriInterface $ connectingTo ,
154
+ float $ socketTimeout ,
155
+ UriInterface $ uri ,
156
+ ?RoutingTable $ table ,
157
+ AuthenticateInterface $ authenticate ,
158
+ string $ userAgent ,
159
+ SessionConfiguration $ config
160
+ ): BoltConnection {
161
+ $ socket = new StreamSocket ($ connectingTo ->getHost (), $ connectingTo ->getPort () ?? 7687 , $ socketTimeout );
162
+
163
+ $ this ->configureSsl ($ uri , $ connectingTo , $ socket , $ table );
164
+
165
+ $ bolt = new Bolt ($ socket );
166
+ $ authenticate ->authenticateBolt ($ bolt , $ connectingTo , $ userAgent );
167
+
168
+ // We create a weak reference to optimise the socket usage. This way the connection can reuse the bolt variable
169
+ // the first time it tries to connect. Only when this function is finished and the returned connection is closed
170
+ // will the reference return null, prompting the need to reopen and recreate the bolt object on the same socket.
171
+ $ originalBolt = WeakReference::create ($ bolt );
172
+
173
+ /**
174
+ * @var array{'name': 0, 'version': 1, 'edition': 2}
175
+ * @psalm-suppress all
176
+ */
177
+ $ fields = array_flip ($ bolt ->run (<<<'CYPHER'
178
+ CALL dbms.components()
179
+ YIELD name, versions, edition
180
+ UNWIND versions AS version
181
+ RETURN name, version, edition
182
+ CYPHER
183
+ )['fields ' ]);
184
+
185
+ /** @var array{0: array{0: string, 1: string, 2: string}} $results */
186
+ $ results = $ bolt ->pullAll ();
187
+
188
+ $ connection = new BoltConnection (
189
+ $ results [0 ][$ fields ['name ' ]].'- ' .$ results [0 ][$ fields ['edition ' ]].'/ ' .$ results [0 ][$ fields ['version ' ]],
190
+ $ connectingTo ,
191
+ $ results [0 ][$ fields ['version ' ]],
192
+ ConnectionProtocol::determineBoltVersion ($ bolt ),
193
+ $ config ->getAccessMode (),
194
+ new DatabaseInfo ($ config ->getDatabase ()),
195
+ $ this ->driverConfig ,
196
+ static function () use ($ socket , $ authenticate , $ connectingTo , $ userAgent , $ originalBolt ) {
197
+ $ bolt = $ originalBolt ->get ();
198
+ if ($ bolt === null ) {
199
+ $ bolt = new Bolt ($ socket );
200
+ $ authenticate ->authenticateBolt ($ bolt , $ connectingTo , $ userAgent );
201
+ }
202
+
203
+ return $ bolt ;
204
+ }
205
+ );
206
+
207
+ $ connection ->open ();
208
+
209
+ return $ connection ;
210
+ }
177
211
}
0 commit comments