use of org.voltcore.messaging.HostMessenger in project voltdb by VoltDB.
the class TestCartographer method testSPMasterChange.
@Test
public void testSPMasterChange() throws Exception {
ZooKeeper zk = getClient(0);
VoltZK.createPersistentZKNodes(zk);
LeaderCache spwriter = new LeaderCache(zk, VoltZK.iv2masters);
HostMessenger hm = mock(HostMessenger.class);
when(hm.getZK()).thenReturn(m_messengers.get(0).getZK());
Cartographer dut = new Cartographer(hm, 0, false);
// Startup partitions
spwriter.start(true);
spwriter.put(0, 0l);
verify(hm, timeout(10000)).send(anyLong(), any(VoltMessage.class));
reset(hm);
spwriter.put(1, 1l);
verify(hm, timeout(10000)).send(anyLong(), any(VoltMessage.class));
reset(hm);
spwriter.put(2, 2l);
verify(hm, timeout(10000)).send(anyLong(), any(VoltMessage.class));
reset(hm);
// now change master for part 0
spwriter.put(0, 3l);
ArgumentCaptor<Long> hsIdCaptor = ArgumentCaptor.forClass(Long.class);
ArgumentCaptor<BinaryPayloadMessage> bpmCaptor = ArgumentCaptor.forClass(BinaryPayloadMessage.class);
verify(hm, timeout(10000)).send(hsIdCaptor.capture(), bpmCaptor.capture());
JSONObject jsObj = new JSONObject(new String(bpmCaptor.getValue().m_payload, "UTF-8"));
System.out.println("BPM: " + jsObj.toString());
final int partitionId = jsObj.getInt(Cartographer.JSON_PARTITION_ID);
final long initiatorHSId = jsObj.getLong(Cartographer.JSON_INITIATOR_HSID);
assertEquals(0, partitionId);
assertEquals(3, initiatorHSId);
spwriter.shutdown();
}
use of org.voltcore.messaging.HostMessenger in project voltdb by VoltDB.
the class TestCartographer method testMPIChange.
@Test
public void testMPIChange() throws Exception {
ZooKeeper zk = getClient(0);
VoltZK.createPersistentZKNodes(zk);
LeaderCache mpwriter = new LeaderCache(zk, VoltZK.iv2mpi);
HostMessenger hm = mock(HostMessenger.class);
when(hm.getZK()).thenReturn(m_messengers.get(0).getZK());
Cartographer dut = new Cartographer(hm, 0, false);
mpwriter.start(true);
// initial master
mpwriter.put(MpInitiator.MP_INIT_PID, 0l);
verify(hm, timeout(10000)).send(anyLong(), any(VoltMessage.class));
reset(hm);
// Now change the master
mpwriter.put(MpInitiator.MP_INIT_PID, 3l);
ArgumentCaptor<Long> hsIdCaptor = ArgumentCaptor.forClass(Long.class);
ArgumentCaptor<BinaryPayloadMessage> bpmCaptor = ArgumentCaptor.forClass(BinaryPayloadMessage.class);
verify(hm, timeout(10000)).send(hsIdCaptor.capture(), bpmCaptor.capture());
JSONObject jsObj = new JSONObject(new String(bpmCaptor.getValue().m_payload, "UTF-8"));
final int partitionId = jsObj.getInt(Cartographer.JSON_PARTITION_ID);
final long initiatorHSId = jsObj.getLong(Cartographer.JSON_INITIATOR_HSID);
assertEquals(MpInitiator.MP_INIT_PID, partitionId);
assertEquals(3, initiatorHSId);
mpwriter.shutdown();
}
use of org.voltcore.messaging.HostMessenger in project voltdb by VoltDB.
the class TestCartographer method testRackAwareRejoin.
@Test
public void testRackAwareRejoin() throws Exception {
ZooKeeper zk = getClient(0);
VoltZK.createPersistentZKNodes(zk);
HostMessenger hm = mock(HostMessenger.class);
when(hm.getZK()).thenReturn(m_messengers.get(0).getZK());
Cartographer dut = new Cartographer(hm, 0, false);
// In total there are 4 partitions, let's say there are two nodes missing
// and one is rejoining back
int kfactor = 1;
int sitesPerHost = 2;
int hostCount = 4;
int totalPartitions = (hostCount * sitesPerHost) / (kfactor + 1);
Map<Integer, String> hostGroups = Maps.newHashMap();
hostGroups.put(0, "rack1");
// this is rejoining node
hostGroups.put(1, "rack1");
hostGroups.put(2, "rack2");
// hostGroups.put(3, "rack2"); // this node is dead
Set<Integer> deadHosts = Sets.newHashSet();
deadHosts.add(1);
deadHosts.add(3);
int rejoiningHostId = 1;
// Depends on number of partitions this part can be slow.
int hostIdCounter = 0;
int[] siteIds = new int[hostCount];
for (int i = 0; i < hostCount; i++) {
siteIds[i] = 0;
}
// assign partitions
for (int pid = 0; pid < totalPartitions; pid++) {
LeaderElector.createRootIfNotExist(zk, LeaderElector.electionDirForPartition(VoltZK.leaders_initiators, pid));
// I'm evil
Thread.sleep(500);
assertFalse(VoltDB.wasCrashCalled);
// add replica
for (int k = 0; k <= kfactor; k++) {
int hid = hostIdCounter++ % hostCount;
if (deadHosts.contains(hid))
continue;
long HSId = CoreUtils.getHSIdFromHostAndSite(hid, siteIds[hid]++);
LeaderElector.createParticipantNode(zk, LeaderElector.electionDirForPartition(VoltZK.leaders_initiators, pid), Long.toString(HSId++), null);
}
}
/*
* Partition layout should be:
* H0: p0, p2
* H1: ?, ? (rejoining, expect p1, p3)
* H2: p1, p3
* H3: p0, p2 (dead)
*/
List<Integer> expectedPartitions = Lists.newArrayList();
expectedPartitions.add(1);
expectedPartitions.add(3);
List<Integer> partitionsToReplace = dut.getIv2PartitionsToReplace(kfactor, sitesPerHost, rejoiningHostId, hostGroups);
assertTrue(partitionsToReplace.size() == sitesPerHost);
for (Integer p : partitionsToReplace) {
assertTrue(expectedPartitions.contains(p));
}
}
use of org.voltcore.messaging.HostMessenger in project voltdb by VoltDB.
the class RealVoltDB method buildClusterMesh.
/**
* Start the voltcore HostMessenger. This joins the node
* to the existing cluster. In the non rejoin case, this
* function will return when the mesh is complete. If
* rejoining, it will return when the node and agreement
* site are synched to the existing cluster.
*/
MeshProber.Determination buildClusterMesh(ReadDeploymentResults readDepl) {
final boolean bareAtStartup = m_config.m_forceVoltdbCreate || pathsWithRecoverableArtifacts(readDepl.deployment).isEmpty();
setBare(bareAtStartup);
final Supplier<Integer> hostCountSupplier = new Supplier<Integer>() {
@Override
public Integer get() {
return m_clusterSettings.get().hostcount();
}
};
ClusterType clusterType = readDepl.deployment.getCluster();
MeshProber criteria = MeshProber.builder().coordinators(m_config.m_coordinators).versionChecker(m_versionChecker).enterprise(m_config.m_isEnterprise).startAction(m_config.m_startAction).bare(bareAtStartup).configHash(CatalogUtil.makeDeploymentHashForConfig(readDepl.deploymentBytes)).hostCountSupplier(hostCountSupplier).kfactor(clusterType.getKfactor()).paused(m_config.m_isPaused).nodeStateSupplier(m_statusTracker.getNodeStateSupplier()).addAllowed(m_config.m_enableAdd).safeMode(m_config.m_safeMode).terminusNonce(getTerminusNonce()).missingHostCount(m_config.m_missingHostCount).build();
HostAndPort hostAndPort = criteria.getLeader();
String hostname = hostAndPort.getHostText();
int port = hostAndPort.getPort();
org.voltcore.messaging.HostMessenger.Config hmconfig;
hmconfig = new org.voltcore.messaging.HostMessenger.Config(hostname, port);
if (m_config.m_placementGroup != null) {
hmconfig.group = m_config.m_placementGroup;
}
hmconfig.internalPort = m_config.m_internalPort;
hmconfig.internalInterface = m_config.m_internalInterface;
hmconfig.zkInterface = m_config.m_zkInterface;
hmconfig.deadHostTimeout = m_config.m_deadHostTimeoutMS;
hmconfig.factory = new VoltDbMessageFactory();
hmconfig.coreBindIds = m_config.m_networkCoreBindings;
hmconfig.acceptor = criteria;
hmconfig.localSitesCount = m_config.m_sitesperhost;
m_messenger = new org.voltcore.messaging.HostMessenger(hmconfig, this);
hostLog.info(String.format("Beginning inter-node communication on port %d.", m_config.m_internalPort));
try {
m_messenger.start();
} catch (Exception e) {
VoltDB.crashLocalVoltDB(e.getMessage(), true, e);
}
VoltZK.createPersistentZKNodes(m_messenger.getZK());
// Use the host messenger's hostId.
m_myHostId = m_messenger.getHostId();
hostLog.info(String.format("Host id of this node is: %d", m_myHostId));
consoleLog.info(String.format("Host id of this node is: %d", m_myHostId));
MeshProber.Determination determination = criteria.waitForDetermination();
// paused is determined in the mesh formation exchanged
if (determination.paused) {
m_messenger.pause();
} else {
m_messenger.unpause();
}
// leader and we're rejoining, this is clearly bad.
if (m_myHostId == 0 && determination.startAction.doesJoin()) {
VoltDB.crashLocalVoltDB("Unable to rejoin a node to itself. " + "Please check your command line and start action and try again.", false, null);
}
// load or store settings form/to zookeeper
if (determination.startAction.doesJoin()) {
m_clusterSettings.load(m_messenger.getZK());
m_clusterSettings.get().store();
} else if (m_myHostId == 0) {
m_clusterSettings.store(m_messenger.getZK());
}
m_clusterCreateTime = m_messenger.getInstanceId().getTimestamp();
return determination;
}
use of org.voltcore.messaging.HostMessenger in project voltdb by VoltDB.
the class VoltDB method dropStackTrace.
/*
* Create a file that starts with the supplied message that contains
* human readable stack traces for all java threads in the current process.
*/
public static void dropStackTrace(String message) {
if (CoreUtils.isJunitTest()) {
VoltLogger log = new VoltLogger("HOST");
log.warn("Declining to drop a stack trace during a junit test.");
return;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSSZ");
String dateString = sdf.format(new Date());
CatalogContext catalogContext = VoltDB.instance().getCatalogContext();
HostMessenger hm = VoltDB.instance().getHostMessenger();
int hostId = 0;
if (hm != null) {
hostId = hm.getHostId();
}
String root = catalogContext != null ? VoltDB.instance().getVoltDBRootPath() + File.separator : "";
try {
PrintWriter writer = new PrintWriter(root + "host" + hostId + "-" + dateString + ".txt");
writer.println(message);
printStackTraces(writer);
writer.flush();
writer.close();
} catch (Exception e) {
try {
VoltLogger log = new VoltLogger("HOST");
log.error("Error while dropping stack trace for \"" + message + "\"", e);
} catch (RuntimeException rt_ex) {
e.printStackTrace();
}
}
}
Aggregations