20
20
21
21
import io .netty .util .concurrent .EventExecutorGroup ;
22
22
23
+ import java .util .LinkedList ;
23
24
import java .util .List ;
24
25
import java .util .concurrent .CompletableFuture ;
25
26
import java .util .concurrent .CompletionStage ;
62
63
public class LoadBalancer implements ConnectionProvider
63
64
{
64
65
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." ;
65
71
private final ConnectionPool connectionPool ;
66
72
private final RoutingTableRegistry routingTables ;
67
73
private final LoadBalancingStrategy loadBalancingStrategy ;
@@ -181,19 +187,23 @@ private CompletionStage<Connection> acquire( AccessMode mode, RoutingTable routi
181
187
{
182
188
AddressSet addresses = addressSet ( mode , routingTable );
183
189
CompletableFuture <Connection > result = new CompletableFuture <>();
184
- acquire ( mode , routingTable , addresses , result );
190
+ List <Throwable > attemptExceptions = new LinkedList <>();
191
+ acquire ( mode , routingTable , addresses , result , attemptExceptions );
185
192
return result ;
186
193
}
187
194
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 )
189
197
{
190
198
BoltServerAddress address = selectAddress ( mode , addresses );
191
199
192
200
if ( address == null )
193
201
{
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 );
197
207
return ;
198
208
}
199
209
@@ -204,10 +214,12 @@ private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet add
204
214
{
205
215
if ( error instanceof ServiceUnavailableException )
206
216
{
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 );
209
221
routingTable .forget ( address );
210
- eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result ) );
222
+ eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result , attemptErrors ) );
211
223
}
212
224
else
213
225
{
0 commit comments