in src/main/java/com/uber/rss/clients/ClientBase.java [142:205]
protected void connectSocket() {
long startTime = System.currentTimeMillis();
int triedTimes = 0;
try {
// we see java.net.UnknownHostException sometimes due to DNS issue, thus retry on this exception
Throwable lastException = null;
while (System.currentTimeMillis() - startTime <= timeoutMillis) {
ClientConnectMetrics metrics = metricGroupContainer.getMetricGroup(getClientConnectMetricsKey());
if (triedTimes >= 1) {
logger.info(String.format("Retrying connect to %s:%s, total retrying times: %s, elapsed milliseconds: %s", host, port, triedTimes, System.currentTimeMillis() - startTime));
metrics.getSocketConnectRetries().update(triedTimes);
}
triedTimes++;
Stopwatch clientConnectLatencyTimerStopwatch = metrics.getSocketConnectLatency().start();
try {
socket = new Socket();
socket.setSoTimeout(timeoutMillis);
socket.setTcpNoDelay(true);
socket.connect(new InetSocketAddress(host, port), timeoutMillis);
break;
} catch (UnknownHostException | NoRouteToHostException | ConnectException socketException) {
if (socketException instanceof ConnectException && !ExceptionUtils.isTimeoutException(socketException)) {
// not timeout exception, e.g. may be connection refused, no need to retry and throw out exception
throw socketException;
}
M3Stats.addException(socketException, this.getClass().getSimpleName());
socket = null;
lastException = socketException;
logger.info(String.format("Failed to connect to %s:%s, %s", host, port, ExceptionUtils.getSimpleMessage(socketException)));
long elapsedTime = System.currentTimeMillis() - startTime;
if (elapsedTime < timeoutMillis) {
ThreadUtils.sleep(Math.min(timeoutMillis - elapsedTime, ThreadUtils.SHORT_WAIT_TIME));
}
} finally {
clientConnectLatencyTimerStopwatch.stop();
}
}
if (socket == null) {
if (lastException != null) {
throw lastException;
} else {
throw new IOException(String.format("Failed to connect to %s:%s", host, port));
}
}
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
connectionInfo = String.format("%s %s [%s -> %s (%s)]",
this.getClass().getSimpleName(),
internalClientId,
socket.getLocalSocketAddress(),
socket.getRemoteSocketAddress(),
host);
} catch (Throwable e) {
M3Stats.addException(e, this.getClass().getSimpleName());
long elapsedTime = System.currentTimeMillis() - startTime;
String msg = String.format("connectSocket failed after trying %s times for %s milliseconds (timeout set to %s): %s, %s", triedTimes, elapsedTime, timeoutMillis, connectionInfo, ExceptionUtils.getSimpleMessage(e));
logger.warn(msg, e);
throw new RssNetworkException(msg, e);
}
}