use of org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryClientReconnectMessage in project ignite by apache.
the class ClientImpl method sendJoinRequest.
/**
* @param recon {@code True} if reconnects.
* @param addr Address.
* @return Socket, connect response and client acknowledge support flag.
*/
@Nullable
private T3<SocketStream, Integer, Boolean> sendJoinRequest(boolean recon, InetSocketAddress addr) {
assert addr != null;
if (log.isDebugEnabled())
log.debug("Send join request [addr=" + addr + ", reconnect=" + recon + ", locNodeId=" + getLocalNodeId() + ']');
Collection<Throwable> errs = null;
long ackTimeout0 = spi.getAckTimeout();
int reconCnt = 0;
int connectAttempts = 1;
int sslConnectAttempts = 3;
UUID locNodeId = getLocalNodeId();
IgniteSpiOperationTimeoutHelper timeoutHelper = new IgniteSpiOperationTimeoutHelper(spi, true);
DiscoveryDataPacket discoveryData = null;
while (true) {
boolean openSock = false;
Socket sock = null;
try {
long tstamp = U.currentTimeMillis();
sock = spi.openSocket(addr, timeoutHelper);
openSock = true;
TcpDiscoveryHandshakeRequest req = new TcpDiscoveryHandshakeRequest(locNodeId);
req.client(true);
spi.writeToSocket(sock, req, timeoutHelper.nextTimeoutChunk(spi.getSocketTimeout()));
TcpDiscoveryHandshakeResponse res = spi.readMessage(sock, null, ackTimeout0);
UUID rmtNodeId = res.creatorNodeId();
assert rmtNodeId != null;
assert !getLocalNodeId().equals(rmtNodeId);
spi.stats.onClientSocketInitialized(U.currentTimeMillis() - tstamp);
locNode.clientRouterNodeId(rmtNodeId);
tstamp = U.currentTimeMillis();
TcpDiscoveryAbstractMessage msg;
if (!recon) {
TcpDiscoveryNode node = locNode;
if (locNode.order() > 0) {
node = locNode.clientReconnectNode(spi.spiCtx.nodeAttributes());
marshalCredentials(node);
}
if (discoveryData == null)
discoveryData = spi.collectExchangeData(new DiscoveryDataPacket(getLocalNodeId()));
msg = new TcpDiscoveryJoinRequestMessage(node, discoveryData);
} else
msg = new TcpDiscoveryClientReconnectMessage(getLocalNodeId(), rmtNodeId, lastMsgId);
msg.client(true);
spi.writeToSocket(sock, msg, timeoutHelper.nextTimeoutChunk(spi.getSocketTimeout()));
spi.stats.onMessageSent(msg, U.currentTimeMillis() - tstamp);
if (log.isDebugEnabled())
log.debug("Message has been sent to address [msg=" + msg + ", addr=" + addr + ", rmtNodeId=" + rmtNodeId + ']');
return new T3<>(new SocketStream(sock), spi.readReceipt(sock, timeoutHelper.nextTimeoutChunk(ackTimeout0)), res.clientAck());
} catch (IOException | IgniteCheckedException e) {
U.closeQuiet(sock);
if (log.isDebugEnabled())
log.error("Exception on joining: " + e.getMessage(), e);
onException("Exception on joining: " + e.getMessage(), e);
if (errs == null)
errs = new ArrayList<>();
errs.add(e);
if (X.hasCause(e, SSLException.class)) {
if (--sslConnectAttempts == 0)
throw new IgniteSpiException("Unable to establish secure connection. " + "Was remote cluster configured with SSL? [rmtAddr=" + addr + ", errMsg=\"" + e.getMessage() + "\"]", e);
continue;
}
if (X.hasCause(e, StreamCorruptedException.class)) {
// StreamCorruptedException could be caused by remote node failover
if (connectAttempts < 2) {
connectAttempts++;
continue;
}
if (log.isDebugEnabled())
log.debug("Connect failed with StreamCorruptedException, skip address: " + addr);
break;
}
if (timeoutHelper.checkFailureTimeoutReached(e))
break;
if (!spi.failureDetectionTimeoutEnabled() && ++reconCnt == spi.getReconnectCount())
break;
if (!openSock) {
// Reconnect for the second time, if connection is not established.
if (connectAttempts < 2) {
connectAttempts++;
continue;
}
// Don't retry if we can not establish connection.
break;
}
if (!spi.failureDetectionTimeoutEnabled() && (e instanceof SocketTimeoutException || X.hasCause(e, SocketTimeoutException.class))) {
ackTimeout0 *= 2;
if (!checkAckTimeout(ackTimeout0))
break;
}
}
}
if (log.isDebugEnabled())
log.debug("Failed to join to address [addr=" + addr + ", recon=" + recon + ", errs=" + errs + ']');
return null;
}
Aggregations