44
44
import org .neo4j .driver .internal .bolt .api .BoltProtocolVersion ;
45
45
import org .neo4j .driver .internal .bolt .api .BoltServerAddress ;
46
46
import org .neo4j .driver .internal .bolt .api .DatabaseName ;
47
+ import org .neo4j .driver .internal .bolt .api .ListenerEvent ;
47
48
import org .neo4j .driver .internal .bolt .api .LoggingProvider ;
48
49
import org .neo4j .driver .internal .bolt .api .MetricsListener ;
49
50
import org .neo4j .driver .internal .bolt .api .NotificationConfig ;
@@ -151,16 +152,16 @@ public CompletionStage<BoltConnection> connect(
151
152
return ;
152
153
}
153
154
154
- var beforeAcquiringOrCreatingEvent = metricsListener .createListenerEvent ();
155
- metricsListener .beforeAcquiringOrCreating (poolId , beforeAcquiringOrCreatingEvent );
155
+ var acquireEvent = metricsListener .createListenerEvent ();
156
+ metricsListener .beforeAcquiringOrCreating (poolId , acquireEvent );
156
157
acquisitionFuture .whenComplete ((connection , throwable ) -> {
157
158
throwable = FutureUtil .completionExceptionCause (throwable );
158
159
if (throwable != null ) {
159
160
if (throwable instanceof TimeoutException ) {
160
161
metricsListener .afterTimedOutToAcquireOrCreate (poolId );
161
162
}
162
163
} else {
163
- metricsListener .afterAcquiredOrCreated (poolId , beforeAcquiringOrCreatingEvent );
164
+ metricsListener .afterAcquiredOrCreated (poolId , acquireEvent );
164
165
}
165
166
metricsListener .afterAcquiringOrCreating (poolId );
166
167
});
@@ -305,24 +306,28 @@ private void connect(
305
306
purge (entry );
306
307
metricsListener .afterConnectionReleased (poolId , inUseEvent );
307
308
});
308
- reauthStage (entryWithMetadata , authMap ).whenComplete ((ignored2 , throwable2 ) -> {
309
- if (!acquisitionFuture .complete (pooledConnection )) {
310
- // acquisition timed out
311
- CompletableFuture <PooledBoltConnection > pendingAcquisition ;
312
- synchronized (this ) {
313
- pendingAcquisition = pendingAcquisitions .poll ();
314
- if (pendingAcquisition == null ) {
315
- // nothing pending, just make the entry available
316
- entry .available = true ;
317
- }
318
- }
319
- if (pendingAcquisition != null ) {
320
- if (pendingAcquisition .complete (pooledConnection )) {
321
- metricsListener .afterConnectionCreated (poolId , inUseEvent );
322
- }
323
- }
309
+ reauthStage (entryWithMetadata , authMap ).whenComplete ((ignored2 , reauthThrowable ) -> {
310
+ if (reauthThrowable != null ) {
311
+ // reauth pipelining failed, purge the connection and try again
312
+ purge (entry );
313
+ connect (
314
+ acquisitionFuture ,
315
+ securityPlan ,
316
+ databaseName ,
317
+ authMap ,
318
+ authMapStageSupplier ,
319
+ mode ,
320
+ bookmarks ,
321
+ impersonatedUser ,
322
+ minVersion ,
323
+ notificationConfig );
324
324
} else {
325
- metricsListener .afterConnectionCreated (poolId , inUseEvent );
325
+ if (!acquisitionFuture .complete (pooledConnection )) {
326
+ // acquisition timed out
327
+ findAndCompletePendingAcquisition (entry , pooledConnection , inUseEvent );
328
+ } else {
329
+ metricsListener .afterConnectionCreated (poolId , inUseEvent );
330
+ }
326
331
}
327
332
});
328
333
}
@@ -394,6 +399,25 @@ private void connect(
394
399
}
395
400
}
396
401
402
+ private void findAndCompletePendingAcquisition (
403
+ ConnectionEntry entry , PooledBoltConnection pooledConnection , ListenerEvent <?> inUseEvent ) {
404
+ CompletableFuture <PooledBoltConnection > pendingAcquisition ;
405
+ synchronized (this ) {
406
+ pendingAcquisition = pendingAcquisitions .poll ();
407
+ if (pendingAcquisition == null ) {
408
+ // nothing pending, just make the entry available
409
+ entry .available = true ;
410
+ }
411
+ }
412
+ if (pendingAcquisition != null ) {
413
+ if (pendingAcquisition .complete (pooledConnection )) {
414
+ metricsListener .afterConnectionCreated (poolId , inUseEvent );
415
+ } else {
416
+ findAndCompletePendingAcquisition (entry , pooledConnection , inUseEvent );
417
+ }
418
+ }
419
+ }
420
+
397
421
private synchronized ConnectionEntryWithMetadata acquireExistingEntry (
398
422
Map <String , Value > authMap , BoltProtocolVersion minVersion ) {
399
423
ConnectionEntryWithMetadata connectionEntryWithMetadata = null ;
@@ -411,6 +435,7 @@ private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
411
435
if (connection .state () != BoltConnectionState .OPEN ) {
412
436
connection .close ();
413
437
iterator .remove ();
438
+ metricsListener .afterClosed (poolId );
414
439
continue ;
415
440
}
416
441
@@ -449,6 +474,7 @@ private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
449
474
throwable .getClass ().getCanonicalName ());
450
475
}
451
476
});
477
+ metricsListener .afterClosed (poolId );
452
478
continue ;
453
479
}
454
480
}
@@ -469,15 +495,7 @@ private CompletionStage<Void> reauthStage(
469
495
.connection
470
496
.logoff ()
471
497
.thenCompose (conn -> conn .logon (authMap ))
472
- .handle ((ignored , throwable ) -> {
473
- if (throwable != null ) {
474
- connectionEntryWithMetadata .connectionEntry .connection .close ();
475
- synchronized (this ) {
476
- pooledConnectionEntries .remove (connectionEntryWithMetadata .connectionEntry );
477
- }
478
- }
479
- return null ;
480
- });
498
+ .thenApply (ignored -> null );
481
499
} else {
482
500
stage = CompletableFuture .completedStage (null );
483
501
}
@@ -562,9 +580,12 @@ public CompletionStage<Void> close() {
562
580
var iterator = pooledConnectionEntries .iterator ();
563
581
while (iterator .hasNext ()) {
564
582
var entry = iterator .next ();
565
- if (entry .connection != null && entry . connection . state () == BoltConnectionState . OPEN ) {
583
+ if (entry .connection != null ) {
566
584
this .closeStage = this .closeStage .thenCompose (
567
- ignored -> entry .connection .close ().exceptionally (throwable -> null ));
585
+ ignored -> entry .connection .close ().handle ((ignored1 , ignored2 ) -> {
586
+ metricsListener .afterClosed (poolId );
587
+ return null ;
588
+ }));
568
589
}
569
590
iterator .remove ();
570
591
}
@@ -627,8 +648,8 @@ private void purge(ConnectionEntry entry) {
627
648
synchronized (this ) {
628
649
pooledConnectionEntries .remove (entry );
629
650
}
630
- metricsListener .afterClosed (poolId );
631
651
entry .connection .close ();
652
+ metricsListener .afterClosed (poolId );
632
653
log .log (System .Logger .Level .DEBUG , "Connection purged from the pool." );
633
654
}
634
655
0 commit comments