diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java index fe033acf1a..adb06f7372 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java @@ -58,7 +58,7 @@ public class RediscoveryImpl implements Rediscovery private static final String RECOVERABLE_ROUTING_ERROR = "Failed to update routing table with server '%s'."; private static final String RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER = "Received a recoverable discovery error with server '%s', " + "will continue discovery with other routing servers if available. " + - "Complete routing failures will be reported separately from this warning."; + "Complete failure is reported separately from this entry."; private final BoltServerAddress initialRouter; private final RoutingSettings settings; diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java index 3a6bd6683f..4109edf30a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancer.java @@ -20,6 +20,7 @@ import io.netty.util.concurrent.EventExecutorGroup; +import java.util.LinkedList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -62,6 +63,11 @@ public class LoadBalancer implements ConnectionProvider { private static final String LOAD_BALANCER_LOG_NAME = "LoadBalancer"; + private static final String CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE = "Connection acquisition failed for all available addresses."; + private static final String CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE = + "Failed to obtain connection towards %s server. Known routing table is: %s"; + private static final String CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE = + "Failed to obtain a connection towards address %s, will try other addresses if available. Complete failure is reported separately from this entry."; private final ConnectionPool connectionPool; private final RoutingTableRegistry routingTables; private final LoadBalancingStrategy loadBalancingStrategy; @@ -181,19 +187,23 @@ private CompletionStage acquire( AccessMode mode, RoutingTable routi { AddressSet addresses = addressSet( mode, routingTable ); CompletableFuture result = new CompletableFuture<>(); - acquire( mode, routingTable, addresses, result ); + List attemptExceptions = new LinkedList<>(); + acquire( mode, routingTable, addresses, result, attemptExceptions ); return result; } - private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet addresses, CompletableFuture result ) + private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet addresses, CompletableFuture result, + List attemptErrors ) { BoltServerAddress address = selectAddress( mode, addresses ); if ( address == null ) { - result.completeExceptionally( new SessionExpiredException( - "Failed to obtain connection towards " + mode + " server. " + - "Known routing table is: " + routingTable ) ); + SessionExpiredException completionError = + new SessionExpiredException( format( CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE, mode, routingTable ) ); + attemptErrors.forEach( completionError::addSuppressed ); + log.error( CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE, completionError ); + result.completeExceptionally( completionError ); return; } @@ -204,10 +214,12 @@ private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet add { if ( error instanceof ServiceUnavailableException ) { - SessionExpiredException errorToLog = new SessionExpiredException( format( "Server at %s is no longer available", address ), error ); - log.warn( "Failed to obtain a connection towards address " + address, errorToLog ); + String attemptMessage = format( CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE, address ); + log.warn( attemptMessage ); + log.debug( attemptMessage, error ); + attemptErrors.add( error ); routingTable.forget( address ); - eventExecutorGroup.next().execute( () -> acquire( mode, routingTable, addresses, result ) ); + eventExecutorGroup.next().execute( () -> acquire( mode, routingTable, addresses, result, attemptErrors ) ); } else {