20
20
21
21
import io .netty .util .concurrent .EventExecutorGroup ;
22
22
23
+ import java .util .ArrayList ;
23
24
import java .util .List ;
24
25
import java .util .concurrent .CompletableFuture ;
25
26
import java .util .concurrent .CompletionStage ;
60
61
public class LoadBalancer implements ConnectionProvider
61
62
{
62
63
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." ;
63
69
private final ConnectionPool connectionPool ;
64
70
private final RoutingTableRegistry routingTables ;
65
71
private final LoadBalancingStrategy loadBalancingStrategy ;
@@ -177,19 +183,23 @@ private CompletionStage<Connection> acquire( AccessMode mode, RoutingTable routi
177
183
{
178
184
AddressSet addresses = addressSet ( mode , routingTable );
179
185
CompletableFuture <Connection > result = new CompletableFuture <>();
180
- acquire ( mode , routingTable , addresses , result );
186
+ List <Throwable > attemptExceptions = new ArrayList <>();
187
+ acquire ( mode , routingTable , addresses , result , attemptExceptions );
181
188
return result ;
182
189
}
183
190
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 )
185
193
{
186
194
BoltServerAddress address = selectAddress ( mode , addresses );
187
195
188
196
if ( address == null )
189
197
{
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 );
193
203
return ;
194
204
}
195
205
@@ -200,10 +210,12 @@ private void acquire( AccessMode mode, RoutingTable routingTable, AddressSet add
200
210
{
201
211
if ( error instanceof ServiceUnavailableException )
202
212
{
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 );
205
217
routingTable .forget ( address );
206
- eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result ) );
218
+ eventExecutorGroup .next ().execute ( () -> acquire ( mode , routingTable , addresses , result , attemptErrors ) );
207
219
}
208
220
else
209
221
{
0 commit comments