use of org.voltcore.network.PicoNetwork in project voltdb by VoltDB.
the class HostMessenger method notifyOfHosts.
/*
* SJ invokes this method after a node finishes connecting to the entire cluster.
* This method constructs all the hosts and puts them in the map
*/
@Override
public void notifyOfHosts(int yourHostId, int[] hosts, SocketChannel[] sockets, InetSocketAddress[] listeningAddresses, Map<Integer, JSONObject> jos) throws Exception {
m_localHostId = yourHostId;
long agreementHSId = getHSIdForLocalSite(AGREEMENT_SITE_ID);
/*
* Construct the set of agreement sites based on all the hosts that are connected
*/
HashSet<Long> agreementSites = new HashSet<Long>();
agreementSites.add(agreementHSId);
//network must be running for register to work
m_network.start();
for (int ii = 0; ii < hosts.length; ii++) {
m_networkLog.info(yourHostId + " notified of host " + hosts[ii]);
agreementSites.add(CoreUtils.getHSIdFromHostAndSite(hosts[ii], AGREEMENT_SITE_ID));
prepSocketChannel(sockets[ii]);
ForeignHost fhost = null;
try {
fhost = new ForeignHost(this, hosts[ii], sockets[ii], m_config.deadHostTimeout, listeningAddresses[ii], new PicoNetwork(sockets[ii]));
putForeignHost(hosts[ii], fhost);
} catch (java.io.IOException e) {
org.voltdb.VoltDB.crashLocalVoltDB("Failed to instantiate foreign host", true, e);
}
}
m_acceptor.accrue(jos);
/*
* Create the local agreement site. It knows that it is recovering because the number of
* prexisting sites is > 0
*/
SiteMailbox sm = new SiteMailbox(this, agreementHSId);
createMailbox(agreementHSId, sm);
m_agreementSite = new AgreementSite(agreementHSId, agreementSites, yourHostId, sm, new InetSocketAddress(m_config.zkInterface.split(":")[0], Integer.parseInt(m_config.zkInterface.split(":")[1])), m_config.backwardsTimeForgivenessWindow, m_failedHostsCallback);
/*
* Now that the agreement site mailbox has been created it is safe
* to enable read
*/
for (ForeignHost fh : m_foreignHosts.values()) {
fh.enableRead(VERBOTEN_THREADS);
}
m_agreementSite.start();
/*
* Do the usual thing of waiting for the agreement site
* to join the cluster and creating the client
*/
VERBOTEN_THREADS.addAll(m_network.getThreadIds());
VERBOTEN_THREADS.addAll(m_agreementSite.getThreadIds());
m_agreementSite.waitForRecovery();
m_zk = org.voltcore.zk.ZKUtil.getClient(m_config.zkInterface, 60 * 1000, VERBOTEN_THREADS);
if (m_zk == null) {
throw new Exception("Timed out trying to connect local ZooKeeper instance");
}
/*
* Publish the address of this node to ZK as seen by the leader
* Also allows waitForGroupJoin to know the number of nodes in the cluster
*/
HostInfo hostInfo;
if (m_config.internalInterface.isEmpty()) {
hostInfo = new HostInfo(new InetSocketAddress(m_joiner.m_reportedInternalInterface, m_config.internalPort).toString(), m_config.group, m_config.localSitesCount);
} else {
hostInfo = new HostInfo(new InetSocketAddress(m_config.internalInterface, m_config.internalPort).toString(), m_config.group, m_config.localSitesCount);
}
m_zk.create(CoreZK.hosts_host + getHostId(), hostInfo.toBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
}
use of org.voltcore.network.PicoNetwork in project voltdb by VoltDB.
the class HostMessenger method notifyOfConnection.
/**
* SocketJoiner receives the request of creating a new connection from given host id,
* create a new ForeignHost for this connection.
*/
@Override
public void notifyOfConnection(int hostId, SocketChannel socket, InetSocketAddress listeningAddress) throws Exception {
m_networkLog.info("Host " + getHostId() + " receives a new connection from host " + hostId);
prepSocketChannel(socket);
// Auxiliary connection never time out
ForeignHost fhost = new ForeignHost(this, hostId, socket, Integer.MAX_VALUE, listeningAddress, new PicoNetwork(socket));
putForeignHost(hostId, fhost);
fhost.enableRead(VERBOTEN_THREADS);
}
use of org.voltcore.network.PicoNetwork in project voltdb by VoltDB.
the class HostMessenger method createAuxiliaryConnections.
// Create connections to nodes within the same partition group
public void createAuxiliaryConnections(Set<Integer> peers, int secondaryConnections) {
for (int hostId : peers) {
for (int ii = 0; ii < secondaryConnections; ii++) {
Iterator<ForeignHost> it = m_foreignHosts.get(hostId).iterator();
if (it.hasNext()) {
ForeignHost fh = it.next();
try {
SocketChannel socket = m_joiner.requestForConnection(fh.m_listeningAddress);
// Auxiliary connection never time out
ForeignHost fhost = new ForeignHost(this, hostId, socket, Integer.MAX_VALUE, fh.m_listeningAddress, new PicoNetwork(socket));
putForeignHost(hostId, fhost);
fhost.enableRead(VERBOTEN_THREADS);
} catch (IOException | JSONException e) {
m_hostLog.error("Failed to connect to peer nodes.", e);
throw new RuntimeException("Failed to establish socket connection with " + fh.m_listeningAddress.getAddress().getHostAddress(), e);
}
}
}
}
m_hasAllSecondaryConnectionCreated = true;
}
use of org.voltcore.network.PicoNetwork in project voltdb by VoltDB.
the class HostMessenger method requestJoin.
/**
* Any node can serve a request to join. The coordination of generating a new host id
* is done via ZK
*
* @param request The requested action from the rejoining host. This is
* opaque to the HostMessenger, it can be any string. The request string can
* be used to make further decision on whether or not to accept the request
* in the MembershipAcceptor.
*/
@Override
public void requestJoin(SocketChannel socket, InetSocketAddress listeningAddress, JSONObject jo) throws Exception {
/*
* Generate the host id via creating an ephemeral sequential node
*/
Integer hostId = selectNewHostId(socket.socket().getInetAddress().getHostAddress());
prepSocketChannel(socket);
ForeignHost fhost = null;
try {
try {
JoinAcceptor.PleaDecision decision = m_acceptor.considerMeshPlea(m_zk, hostId, jo);
/*
* Write the response that advertises the cluster topology
*/
writeRequestJoinResponse(hostId, decision, socket);
if (!decision.accepted) {
socket.close();
return;
}
/*
* Wait for the a response from the joining node saying that it connected
* to all the nodes we just advertised. Use a timeout so that the cluster can't be stuck
* on failed joins.
*/
ByteBuffer finishedJoining = ByteBuffer.allocate(1);
socket.configureBlocking(false);
long start = System.currentTimeMillis();
while (finishedJoining.hasRemaining() && System.currentTimeMillis() - start < 120000) {
int read = socket.read(finishedJoining);
if (read == -1) {
m_networkLog.info("New connection was unable to establish mesh");
socket.close();
return;
} else if (read < 1) {
Thread.sleep(5);
}
}
/*
* Now add the host to the mailbox system
*/
fhost = new ForeignHost(this, hostId, socket, m_config.deadHostTimeout, listeningAddress, new PicoNetwork(socket));
putForeignHost(hostId, fhost);
fhost.enableRead(VERBOTEN_THREADS);
m_acceptor.accrue(hostId, jo);
} catch (Exception e) {
m_networkLog.error("Error joining new node", e);
addFailedHost(hostId);
removeForeignHost(hostId);
m_acceptor.detract(hostId);
socket.close();
return;
}
/*
* And the last step is to wait for the new node to join ZooKeeper.
* This node is the one to create the txn that will add the new host to the list of hosts
* with agreement sites across the cluster.
*/
long hsId = CoreUtils.getHSIdFromHostAndSite(hostId, AGREEMENT_SITE_ID);
if (!m_agreementSite.requestJoin(hsId).await(60, TimeUnit.SECONDS)) {
reportForeignHostFailed(hostId);
}
} catch (Throwable e) {
org.voltdb.VoltDB.crashLocalVoltDB("", true, e);
}
}
Aggregations