};
@SuppressWarnings("unchecked")
public static <CLIENT, T> T execute(List<Connection> connections, AbstractCommand<CLIENT, T> command, int maxRetries,
long backOffTime, long maxBackOffTime) throws BlurException, TException, IOException {
Tracer traceSetup = Trace.trace("execute - setup");
LocalResources localResources = new LocalResources();
AtomicReference<Client> client = localResources.client;
AtomicInteger retries = localResources.retries;
List<Connection> shuffledConnections = localResources.shuffledConnections;
retries.set(0);
shuffledConnections.addAll(connections);
Collections.shuffle(shuffledConnections, _random.get());
boolean allBad = true;
int connectionErrorCount = 0;
traceSetup.done();
while (true) {
for (Connection connection : shuffledConnections) {
Tracer traceConnectionSetup = Trace.trace("execute - connection setup");
try {
if (isBadConnection(connection)) {
continue;
}
client.set(null);
try {
client.set(_clientPool.getClient(connection));
} catch (IOException e) {
if (handleError(connection, client, retries, command, e, maxRetries, backOffTime, maxBackOffTime)) {
throw e;
} else {
markBadConnection(connection);
continue;
}
}
} finally {
traceConnectionSetup.done();
}
Tracer trace = null;
try {
User user = UserConverter.toThriftUser(UserContext.getUser());
client.get().setUser(user);
TraceId traceId = Trace.getTraceId();
if (traceId != null) {
client.get().startTrace(traceId.getRootId(), traceId.getRequestId());
trace = Trace.trace("thrift client", Trace.param("connection", getConnectionStr(client.get())));
}
T result = command.call((CLIENT) client.get(), connection);
allBad = false;
if (command.isDetachClient()) {
// if the is detach client is set then the command will return the
// client to the pool.
client.set(null);
}
return result;
} catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof TTransportException) {
TTransportException t = (TTransportException) cause;
if (handleError(connection, client, retries, command, t, maxRetries, backOffTime, maxBackOffTime)) {
Throwable c = t.getCause();
if (cause instanceof SocketTimeoutException) {
throw new BlurException(c.getMessage(), BException.toString(c), ErrorType.REQUEST_TIMEOUT);
}
throw t;
}
} else {
throw e;
}
} catch (TTransportException e) {
if (handleError(connection, client, retries, command, e, maxRetries, backOffTime, maxBackOffTime)) {
Throwable c = e.getCause();
if (c instanceof SocketTimeoutException) {
throw new BlurException(c.getMessage(), BException.toString(c), ErrorType.REQUEST_TIMEOUT);
}
throw e;
}
} finally {
if (trace != null) {
trace.done();
}
if (client.get() != null) {
returnClient(connection, client);
}
}