2020
2121import io .netty .util .concurrent .EventExecutorGroup ;
2222
23+ import java .util .ArrayList ;
2324import java .util .List ;
2425import java .util .concurrent .CompletableFuture ;
2526import java .util .concurrent .CompletionStage ;
6061public class LoadBalancer implements ConnectionProvider
6162{
6263 private static final String LOAD_BALANCER_LOG_NAME = "LoadBalancer" ;
64+ private static final String CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE = "Connection acquisition failed for all available addresses." ;
65+ private static final String CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE =
66+ "Failed to obtain connection towards %s server. Known routing table is: %s" ;
67+ private static final String CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE =
68+ "Failed to obtain a connection towards address %s, will try other addresses if available. Complete failure is reported separately from this entry." ;
6369 private final ConnectionPool connectionPool ;
6470 private final RoutingTableRegistry routingTables ;
6571 private final LoadBalancingStrategy loadBalancingStrategy ;
@@ -177,19 +183,23 @@ private CompletionStage<Connection> acquire( AccessMode mode, RoutingTable routi
177183 {
178184 AddressSet addresses = addressSet ( mode , routingTable );
179185 CompletableFuture <Connection > result = new CompletableFuture <>();
180- acquire ( mode , routingTable , addresses , result );
186+ List <Throwable > attemptExceptions = new ArrayList <>();
187+ acquire ( mode , routingTable , addresses , result , attemptExceptions );
181188 return result ;
182189 }
183190
184- private void acquire ( AccessMode mode , RoutingTable routingTable , AddressSet addresses , CompletableFuture <Connection > result )
191+ private void acquire ( AccessMode mode , RoutingTable routingTable , AddressSet addresses , CompletableFuture <Connection > result ,
192+ List <Throwable > attemptErrors )
185193 {
186194 BoltServerAddress address = selectAddress ( mode , addresses );
187195
188196 if ( address == null )
189197 {
190- result .completeExceptionally ( new SessionExpiredException (
191- "Failed to obtain connection towards " + mode + " server. " +
192- "Known routing table is: " + routingTable ) );
198+ SessionExpiredException completionError =
199+ new SessionExpiredException ( format ( CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE , mode , routingTable ) );
200+ attemptErrors .forEach ( completionError ::addSuppressed );
201+ log .error ( CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE , completionError );
202+ result .completeExceptionally ( completionError );
193203 return ;
194204 }
195205
@@ -200,10 +210,12 @@ private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet add
200210 {
201211 if ( error instanceof ServiceUnavailableException )
202212 {
203- SessionExpiredException errorToLog = new SessionExpiredException ( format ( "Server at %s is no longer available" , address ), error );
204- log .warn ( "Failed to obtain a connection towards address " + address , errorToLog );
213+ String attemptMessage = format ( CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE , address );
214+ log .warn ( attemptMessage );
215+ log .debug ( attemptMessage , error );
216+ attemptErrors .add ( error );
205217 routingTable .forget ( address );
206- eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result ) );
218+ eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result , attemptErrors ) );
207219 }
208220 else
209221 {
0 commit comments