String localVersionString = VoltDB.instance().getVersionString();
String localBuildString = VoltDB.instance().getBuildString();
activeVersions.add(localVersionString);
JSONObject jsObj = new JSONObject();
jsObj.put("type", "REQUEST_HOSTID");
// put the version compatibility status in the json
jsObj.put("versionString", localVersionString);
/*
* Advertise the port we are going to listen on based on
* config
*/
jsObj.put("port", m_internalPort);
/*
* If config specified an internal interface use that.
* Otherwise the leader will echo back what we connected on
*/
if (!m_internalInterface.isEmpty()) {
jsObj.put("address", m_internalInterface);
}
byte jsBytes[] = jsObj.toString(4).getBytes(Constants.UTF8ENCODING);
ByteBuffer requestHostIdBuffer = ByteBuffer.allocate(4 + jsBytes.length);
requestHostIdBuffer.putInt(jsBytes.length);
requestHostIdBuffer.put(jsBytes).flip();
while (requestHostIdBuffer.hasRemaining()) {
socket.write(requestHostIdBuffer);
}
// read the json response from socketjoiner with version info and validate it
processVersionJSONResponse(socket, remoteAddress, localVersionString, localBuildString, activeVersions);
// read the json response sent by HostMessenger with HostID
JSONObject jsonObj = readJSONObjFromWire(socket, remoteAddress);
/*
* Get the generated host id, and the interface we connected on
* that was echoed back
*/
m_localHostId = jsonObj.getInt("newHostId");
m_reportedInternalInterface = jsonObj.getString("reportedAddress");
/*
* Loop over all the hosts and create a connection (except for the first entry, that is the leader)
* and publish the host id that was generated. This finishes creating the mesh
*/
JSONArray otherHosts = jsonObj.getJSONArray("hosts");
int hostIds[] = new int[otherHosts.length()];
SocketChannel hostSockets[] = new SocketChannel[hostIds.length];
InetSocketAddress listeningAddresses[] = new InetSocketAddress[hostIds.length];
for (int ii = 0; ii < otherHosts.length(); ii++) {
JSONObject host = otherHosts.getJSONObject(ii);
String address = host.getString("address");
int port = host.getInt("port");
final int hostId = host.getInt("hostId");
LOG.info("Leader provided address " + address + ":" + port);
InetSocketAddress hostAddr = new InetSocketAddress(address, port);
if (ii == 0) {
//Leader already has a socket
hostIds[ii] = hostId;
listeningAddresses[ii] = hostAddr;
hostSockets[ii] = socket;
continue;
}
SocketChannel hostSocket = null;
while (hostSocket == null) {
try {
hostSocket = SocketChannel.open(hostAddr);
}
catch (java.net.ConnectException e) {
LOG.warn("Joining host failed: " + e.getMessage() + " retrying..");
try {
Thread.sleep(250); // milliseconds
}
catch (InterruptedException ex) {
// don't really care.
}
}
}
/*
* Get the clock skew value
*/
currentTimeBuf.clear();
while (currentTimeBuf.hasRemaining()) {
hostSocket.read(currentTimeBuf);
}
currentTimeBuf.flip();
skew = System.currentTimeMillis() - currentTimeBuf.getLong();
assert(currentTimeBuf.remaining() == 0);
skews.add(skew);
jsObj = new JSONObject();
jsObj.put("type", "PUBLISH_HOSTID");
jsObj.put("hostId", m_localHostId);
jsObj.put("port", m_internalPort);
jsObj.put(
"address",