Skip to content

Commit 385d38e

Browse files
committed
Update internal metrics handling
Make sure `afterClosed` is called whenever a pooled connection is closed. In addition, handle reauth pipelining error.
1 parent 31b8f96 commit 385d38e

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

bolt-api-pooled/src/main/java/org/neo4j/driver/internal/bolt/pooledimpl/PooledBoltConnectionProvider.java

+53-32
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.neo4j.driver.internal.bolt.api.BoltProtocolVersion;
4646
import org.neo4j.driver.internal.bolt.api.BoltServerAddress;
4747
import org.neo4j.driver.internal.bolt.api.DatabaseName;
48+
import org.neo4j.driver.internal.bolt.api.ListenerEvent;
4849
import org.neo4j.driver.internal.bolt.api.LoggingProvider;
4950
import org.neo4j.driver.internal.bolt.api.MetricsListener;
5051
import org.neo4j.driver.internal.bolt.api.NotificationConfig;
@@ -158,16 +159,16 @@ public CompletionStage<BoltConnection> connect(
158159
return;
159160
}
160161

161-
var beforeAcquiringOrCreatingEvent = metricsListener.createListenerEvent();
162-
metricsListener.beforeAcquiringOrCreating(poolId, beforeAcquiringOrCreatingEvent);
162+
var acquireEvent = metricsListener.createListenerEvent();
163+
metricsListener.beforeAcquiringOrCreating(poolId, acquireEvent);
163164
acquisitionFuture.whenComplete((connection, throwable) -> {
164165
throwable = FutureUtil.completionExceptionCause(throwable);
165166
if (throwable != null) {
166167
if (throwable instanceof TimeoutException) {
167168
metricsListener.afterTimedOutToAcquireOrCreate(poolId);
168169
}
169170
} else {
170-
metricsListener.afterAcquiredOrCreated(poolId, beforeAcquiringOrCreatingEvent);
171+
metricsListener.afterAcquiredOrCreated(poolId, acquireEvent);
171172
}
172173
metricsListener.afterAcquiringOrCreating(poolId);
173174
});
@@ -312,24 +313,28 @@ private void connect(
312313
purge(entry);
313314
metricsListener.afterConnectionReleased(poolId, inUseEvent);
314315
});
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);
331331
} 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+
}
333338
}
334339
});
335340
}
@@ -408,6 +413,25 @@ private void connect(
408413
}
409414
}
410415

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+
411435
private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
412436
AuthToken authToken, BoltProtocolVersion minVersion) {
413437
ConnectionEntryWithMetadata connectionEntryWithMetadata = null;
@@ -425,6 +449,7 @@ private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
425449
if (connection.state() != BoltConnectionState.OPEN) {
426450
connection.close();
427451
iterator.remove();
452+
metricsListener.afterClosed(poolId);
428453
continue;
429454
}
430455

@@ -463,6 +488,7 @@ private synchronized ConnectionEntryWithMetadata acquireExistingEntry(
463488
throwable.getClass().getCanonicalName());
464489
}
465490
});
491+
metricsListener.afterClosed(poolId);
466492
continue;
467493
}
468494
}
@@ -483,15 +509,7 @@ private CompletionStage<Void> reauthStage(
483509
.connection
484510
.logoff()
485511
.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);
495513
} else {
496514
stage = CompletableFuture.completedStage(null);
497515
}
@@ -612,9 +630,12 @@ public CompletionStage<Void> close() {
612630
var iterator = pooledConnectionEntries.iterator();
613631
while (iterator.hasNext()) {
614632
var entry = iterator.next();
615-
if (entry.connection != null && entry.connection.state() == BoltConnectionState.OPEN) {
633+
if (entry.connection != null) {
616634
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+
}));
618639
}
619640
iterator.remove();
620641
}
@@ -677,8 +698,8 @@ private void purge(ConnectionEntry entry) {
677698
synchronized (this) {
678699
pooledConnectionEntries.remove(entry);
679700
}
680-
metricsListener.afterClosed(poolId);
681701
entry.connection.close();
702+
metricsListener.afterClosed(poolId);
682703
log.log(System.Logger.Level.DEBUG, "Connection purged from the pool.");
683704
}
684705

0 commit comments

Comments
 (0)