2020
2121import io .netty .util .concurrent .EventExecutorGroup ;
2222
23+ import java .util .LinkedList ;
2324import java .util .List ;
2425import java .util .concurrent .CompletableFuture ;
2526import java .util .concurrent .CompletionStage ;
6263public class LoadBalancer implements ConnectionProvider
6364{
6465 private static final String LOAD_BALANCER_LOG_NAME = "LoadBalancer" ;
66+ private static final String CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE = "Connection acquisition failed for all available addresses." ;
67+ private static final String CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE =
68+ "Failed to obtain connection towards %s server. Known routing table is: %s" ;
69+ private static final String CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE =
70+ "Failed to obtain a connection towards address %s, will try other addresses if available. Complete failure is reported separately from this entry." ;
6571 private final ConnectionPool connectionPool ;
6672 private final RoutingTableRegistry routingTables ;
6773 private final LoadBalancingStrategy loadBalancingStrategy ;
@@ -181,19 +187,23 @@ private CompletionStage<Connection> acquire( AccessMode mode, RoutingTable routi
181187 {
182188 AddressSet addresses = addressSet ( mode , routingTable );
183189 CompletableFuture <Connection > result = new CompletableFuture <>();
184- acquire ( mode , routingTable , addresses , result );
190+ List <Throwable > attemptExceptions = new LinkedList <>();
191+ acquire ( mode , routingTable , addresses , result , attemptExceptions );
185192 return result ;
186193 }
187194
188- private void acquire ( AccessMode mode , RoutingTable routingTable , AddressSet addresses , CompletableFuture <Connection > result )
195+ private void acquire ( AccessMode mode , RoutingTable routingTable , AddressSet addresses , CompletableFuture <Connection > result ,
196+ List <Throwable > attemptErrors )
189197 {
190198 BoltServerAddress address = selectAddress ( mode , addresses );
191199
192200 if ( address == null )
193201 {
194- result .completeExceptionally ( new SessionExpiredException (
195- "Failed to obtain connection towards " + mode + " server. " +
196- "Known routing table is: " + routingTable ) );
202+ SessionExpiredException completionError =
203+ new SessionExpiredException ( format ( CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE , mode , routingTable ) );
204+ attemptErrors .forEach ( completionError ::addSuppressed );
205+ log .error ( CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE , completionError );
206+ result .completeExceptionally ( completionError );
197207 return ;
198208 }
199209
@@ -204,10 +214,12 @@ private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet add
204214 {
205215 if ( error instanceof ServiceUnavailableException )
206216 {
207- SessionExpiredException errorToLog = new SessionExpiredException ( format ( "Server at %s is no longer available" , address ), error );
208- log .warn ( "Failed to obtain a connection towards address " + address , errorToLog );
217+ String attemptMessage = format ( CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE , address );
218+ log .warn ( attemptMessage );
219+ log .debug ( attemptMessage , error );
220+ attemptErrors .add ( error );
209221 routingTable .forget ( address );
210- eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result ) );
222+ eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result , attemptErrors ) );
211223 }
212224 else
213225 {
0 commit comments