45
45
import org .neo4j .driver .internal .bolt .api .BoltProtocolVersion ;
46
46
import org .neo4j .driver .internal .bolt .api .BoltServerAddress ;
47
47
import org .neo4j .driver .internal .bolt .api .DatabaseName ;
48
+ import org .neo4j .driver .internal .bolt .api .ListenerEvent ;
48
49
import org .neo4j .driver .internal .bolt .api .LoggingProvider ;
49
50
import org .neo4j .driver .internal .bolt .api .MetricsListener ;
50
51
import org .neo4j .driver .internal .bolt .api .NotificationConfig ;
@@ -158,16 +159,16 @@ public CompletionStage<BoltConnection> connect(
158
159
return ;
159
160
}
160
161
161
- var beforeAcquiringOrCreatingEvent = metricsListener .createListenerEvent ();
162
- metricsListener .beforeAcquiringOrCreating (poolId , beforeAcquiringOrCreatingEvent );
162
+ var acquireEvent = metricsListener .createListenerEvent ();
163
+ metricsListener .beforeAcquiringOrCreating (poolId , acquireEvent );
163
164
acquisitionFuture .whenComplete ((connection , throwable ) -> {
164
165
throwable = FutureUtil .completionExceptionCause (throwable );
165
166
if (throwable != null ) {
166
167
if (throwable instanceof TimeoutException ) {
167
168
metricsListener .afterTimedOutToAcquireOrCreate (poolId );
168
169
}
169
170
} else {
170
- metricsListener .afterAcquiredOrCreated (poolId , beforeAcquiringOrCreatingEvent );
171
+ metricsListener .afterAcquiredOrCreated (poolId , acquireEvent );
171
172
}
172
173
metricsListener .afterAcquiringOrCreating (poolId );
173
174
});
@@ -312,24 +313,28 @@ private void connect(
312
313
purge (entry );
313
314
metricsListener .afterConnectionReleased (poolId , inUseEvent );
314
315
});
315
- reauthStage (entryWithMetadata , authToken ).whenComplete ((ignored2 , throwable2 ) -> {
316
- if (!acquisitionFuture .complete (pooledConnection )) {
317
- // acquisition timed out
318
- CompletableFuture <PooledBoltConnection > pendingAcquisition ;
319
- synchronized (this ) {
320
- pendingAcquisition = pendingAcquisitions .poll ();
321
- if (pendingAcquisition == null ) {
322
- // nothing pending, just make the entry available
323
- entry .available = true ;
324
- }
325
- }
326
- if (pendingAcquisition != null ) {
327
- if (pendingAcquisition .complete (pooledConnection )) {
328
- metricsListener .afterConnectionCreated (poolId , inUseEvent );
329
- }
330
- }
316
+ reauthStage (entryWithMetadata , authToken ).whenComplete ((ignored2 , reauthThrowable ) -> {
317
+ if (reauthThrowable != null ) {
318
+ // reauth pipelining failed, purge the connection and try again
319
+ purge (entry );
320
+ connect (
321
+ acquisitionFuture ,
322
+ securityPlan ,
323
+ databaseName ,
324
+ authToken ,
325
+ authTokenStageSupplier ,
326
+ mode ,
327
+ bookmarks ,
328
+ impersonatedUser ,
329
+ minVersion ,
330
+ notificationConfig );
331
331
} else {
332
- metricsListener .afterConnectionCreated (poolId , inUseEvent );
332
+ if (!acquisitionFuture .complete (pooledConnection )) {
333
+ // acquisition timed out
334
+ findAndCompletePendingAcquisition (entry , pooledConnection , inUseEvent );
335
+ } else {
336
+ metricsListener .afterConnectionCreated (poolId , inUseEvent );
337
+ }
333
338
}
334
339
});
335
340
}
@@ -408,6 +413,25 @@ private void connect(
408
413
}
409
414
}
410
415
416
+ private void findAndCompletePendingAcquisition (
417
+ ConnectionEntry entry , PooledBoltConnection pooledConnection , ListenerEvent <?> inUseEvent ) {
418
+ CompletableFuture <PooledBoltConnection > pendingAcquisition ;
419
+ synchronized (this ) {
420
+ pendingAcquisition = pendingAcquisitions .poll ();
421
+ if (pendingAcquisition == null ) {
422
+ // nothing pending, just make the entry available
423
+ entry .available = true ;
424
+ }
425
+ }
426
+ if (pendingAcquisition != null ) {
427
+ if (pendingAcquisition .complete (pooledConnection )) {
428
+ metricsListener .afterConnectionCreated (poolId , inUseEvent );
429
+ } else {
430
+ findAndCompletePendingAcquisition (entry , pooledConnection , inUseEvent );
431
+ }
432
+ }
433
+ }
434
+
411
435
private synchronized ConnectionEntryWithMetadata acquireExistingEntry (
412
436
AuthToken authToken , BoltProtocolVersion minVersion ) {
413
437
ConnectionEntryWithMetadata connectionEntryWithMetadata = null ;
@@ -425,6 +449,7 @@ private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
425
449
if (connection .state () != BoltConnectionState .OPEN ) {
426
450
connection .close ();
427
451
iterator .remove ();
452
+ metricsListener .afterClosed (poolId );
428
453
continue ;
429
454
}
430
455
@@ -463,6 +488,7 @@ private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
463
488
throwable .getClass ().getCanonicalName ());
464
489
}
465
490
});
491
+ metricsListener .afterClosed (poolId );
466
492
continue ;
467
493
}
468
494
}
@@ -483,15 +509,7 @@ private CompletionStage<Void> reauthStage(
483
509
.connection
484
510
.logoff ()
485
511
.thenCompose (conn -> conn .logon (authToken ))
486
- .handle ((ignored , throwable ) -> {
487
- if (throwable != null ) {
488
- connectionEntryWithMetadata .connectionEntry .connection .close ();
489
- synchronized (this ) {
490
- pooledConnectionEntries .remove (connectionEntryWithMetadata .connectionEntry );
491
- }
492
- }
493
- return null ;
494
- });
512
+ .thenApply (ignored -> null );
495
513
} else {
496
514
stage = CompletableFuture .completedStage (null );
497
515
}
@@ -612,9 +630,12 @@ public CompletionStage<Void> close() {
612
630
var iterator = pooledConnectionEntries .iterator ();
613
631
while (iterator .hasNext ()) {
614
632
var entry = iterator .next ();
615
- if (entry .connection != null && entry . connection . state () == BoltConnectionState . OPEN ) {
633
+ if (entry .connection != null ) {
616
634
this .closeStage = this .closeStage .thenCompose (
617
- ignored -> entry .connection .close ().exceptionally (throwable -> null ));
635
+ ignored -> entry .connection .close ().handle ((ignored1 , ignored2 ) -> {
636
+ metricsListener .afterClosed (poolId );
637
+ return null ;
638
+ }));
618
639
}
619
640
iterator .remove ();
620
641
}
@@ -677,8 +698,8 @@ private void purge(ConnectionEntry entry) {
677
698
synchronized (this ) {
678
699
pooledConnectionEntries .remove (entry );
679
700
}
680
- metricsListener .afterClosed (poolId );
681
701
entry .connection .close ();
702
+ metricsListener .afterClosed (poolId );
682
703
log .log (System .Logger .Level .DEBUG , "Connection purged from the pool." );
683
704
}
684
705
0 commit comments