use of org.apache.helix.NotificationContext in project pinot by linkedin.
the class BaseClusterIntegrationTest method setupSegmentCountCountDownLatch.
protected CountDownLatch setupSegmentCountCountDownLatch(final String tableName, final int expectedSegmentCount) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
HelixManager manager = HelixManagerFactory.getZKHelixManager(getHelixClusterName(), "test_instance", InstanceType.SPECTATOR, ZkStarter.DEFAULT_ZK_STR);
manager.connect();
manager.addExternalViewChangeListener(new ExternalViewChangeListener() {
private boolean _hasBeenTriggered = false;
@Override
public void onExternalViewChange(List<ExternalView> externalViewList, NotificationContext changeContext) {
// Nothing to do?
if (_hasBeenTriggered) {
return;
}
for (ExternalView externalView : externalViewList) {
if (externalView.getId().contains(tableName)) {
Set<String> partitionSet = externalView.getPartitionSet();
if (partitionSet.size() == expectedSegmentCount) {
int onlinePartitionCount = 0;
for (String partitionId : partitionSet) {
Map<String, String> partitionStateMap = externalView.getStateMap(partitionId);
if (partitionStateMap.containsValue("ONLINE")) {
onlinePartitionCount++;
}
}
if (onlinePartitionCount == expectedSegmentCount) {
// System.out.println("Got " + expectedSegmentCount + " online tables, unlatching the main thread");
latch.countDown();
_hasBeenTriggered = true;
}
}
}
}
}
});
return latch;
}
use of org.apache.helix.NotificationContext in project incubator-gobblin by apache.
the class GobblinClusterManager method connectHelixManager.
@VisibleForTesting
void connectHelixManager() {
try {
this.isLeader = false;
this.helixManager.connect();
this.helixManager.addLiveInstanceChangeListener(new GobblinLiveInstanceChangeListener());
this.helixManager.getMessagingService().registerMessageHandlerFactory(GobblinHelixConstants.SHUTDOWN_MESSAGE_TYPE, new ControllerShutdownMessageHandlerFactory());
this.helixManager.getMessagingService().registerMessageHandlerFactory(Message.MessageType.USER_DEFINE_MSG.toString(), getUserDefinedMessageHandlerFactory());
// standalone mode listens for controller change
if (this.isStandaloneMode) {
// Subscribe to leadership changes
this.helixManager.addControllerListener(new ControllerChangeListener() {
@Override
public void onControllerChange(NotificationContext changeContext) {
handleLeadershipChange(changeContext);
}
});
}
} catch (Exception e) {
LOGGER.error("HelixManager failed to connect", e);
throw Throwables.propagate(e);
}
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class HelixTaskExecutor method scheduleTask.
@Override
public boolean scheduleTask(MessageTask task) {
String taskId = task.getTaskId();
Message message = task.getMessage();
NotificationContext notificationContext = task.getNotificationContext();
HelixManager manager = notificationContext.getManager();
try {
// Check to see if dedicate thread pool for handling state transition messages is configured or provided.
updateStateTransitionMessageThreadPool(message, manager);
LOG.info("Scheduling message: " + taskId);
// System.out.println("sched msg: " + message.getPartitionName() + "-"
// + message.getTgtName() + "-" + message.getFromState() + "-"
// + message.getToState());
_statusUpdateUtil.logInfo(message, HelixTaskExecutor.class, "Message handling task scheduled", manager);
// sync'ed
synchronized (_lock) {
if (!_taskMap.containsKey(taskId)) {
ExecutorService exeSvc = findExecutorServiceForMsg(message);
if (exeSvc == null) {
LOG.warn(String.format("Threadpool is null for type %s of message %s", message.getMsgType(), message.getMsgId()));
return false;
}
LOG.info("Submit task: " + taskId + " to pool: " + exeSvc);
Future<HelixTaskResult> future = exeSvc.submit(task);
_messageTaskMap.putIfAbsent(getMessageTarget(message.getResourceName(), message.getPartitionName()), taskId);
TimerTask timerTask = null;
if (message.getExecutionTimeout() > 0) {
timerTask = new MessageTimeoutTask(this, task);
_timer.schedule(timerTask, message.getExecutionTimeout());
LOG.info("Message starts with timeout " + message.getExecutionTimeout() + " MsgId: " + task.getTaskId());
} else {
LOG.debug("Message does not have timeout. MsgId: " + task.getTaskId());
}
_taskMap.put(taskId, new MessageTaskInfo(task, future, timerTask));
LOG.info("Message: " + taskId + " handling task scheduled");
return true;
} else {
_statusUpdateUtil.logWarning(message, HelixTaskExecutor.class, "Message handling task already sheduled for " + taskId, manager);
}
}
} catch (Exception e) {
LOG.error("Error while executing task. " + message, e);
_statusUpdateUtil.logError(message, HelixTaskExecutor.class, e, "Error while executing task " + e, manager);
}
return false;
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class TestZkCallbackHandlerLeak method testRemoveUserCbHdlrOnPathRemoval.
@Test
public void testRemoveUserCbHdlrOnPathRemoval() throws Exception {
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
final int n = 3;
final String zkAddr = ZK_ADDR;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// resource
TestHelper.setupCluster(// resource
clusterName, // resource
zkAddr, // resource
12918, // resource
"localhost", // resource
"TestDB", // resource
1, // partitions
32, // nodes
n, // replicas
2, "MasterSlave", true);
final ClusterControllerManager controller = new ClusterControllerManager(zkAddr, clusterName, "controller");
controller.syncStart();
MockParticipantManager[] participants = new MockParticipantManager[n];
for (int i = 0; i < n; i++) {
String instanceName = "localhost_" + (12918 + i);
participants[i] = new MockParticipantManager(zkAddr, clusterName, instanceName);
participants[i].syncStart();
// register a controller listener on participant_0
if (i == 0) {
MockParticipantManager manager = participants[0];
manager.addCurrentStateChangeListener(new CurrentStateChangeListener() {
@Override
public void onStateChange(String instanceName, List<CurrentState> statesInfo, NotificationContext changeContext) {
// To change body of implemented methods use File | Settings | File Templates.
// System.out.println(instanceName + " on current-state change, type: " +
// changeContext.getType());
}
}, manager.getInstanceName(), manager.getSessionId());
}
}
HelixClusterVerifier verifier = new BestPossibleExternalViewVerifier.Builder(clusterName).setZkAddr(zkAddr).build();
Assert.assertTrue(verifier.verify());
MockParticipantManager participantToExpire = participants[0];
String oldSessionId = participantToExpire.getSessionId();
PropertyKey.Builder keyBuilder = new PropertyKey.Builder(clusterName);
// check manager#hanlders
Assert.assertEquals(participantToExpire.getHandlers().size(), 2, "Should have 2 handlers: CURRENTSTATE/{sessionId}, and MESSAGES");
// check zkclient#listeners
Map<String, Set<IZkDataListener>> dataListeners = ZkTestHelper.getZkDataListener(participantToExpire.getZkClient());
Map<String, Set<IZkChildListener>> childListeners = ZkTestHelper.getZkChildListener(participantToExpire.getZkClient());
// printZkListeners(participantToExpire.getZkClient());
Assert.assertEquals(dataListeners.size(), 1, "Should have 1 path (CURRENTSTATE/{sessionId}/TestDB0) which has 1 data-listeners");
String path = keyBuilder.currentState(participantToExpire.getInstanceName(), oldSessionId, "TestDB0").getPath();
Assert.assertEquals(dataListeners.get(path).size(), 1, "Should have 1 data-listeners on path: " + path);
Assert.assertEquals(childListeners.size(), 2, "Should have 2 paths (CURRENTSTATE/{sessionId}, and MESSAGES) each of which has 1 child-listener");
path = keyBuilder.currentStates(participantToExpire.getInstanceName(), oldSessionId).getPath();
Assert.assertEquals(childListeners.get(path).size(), 1, "Should have 1 child-listener on path: " + path);
path = keyBuilder.messages(participantToExpire.getInstanceName()).getPath();
Assert.assertEquals(childListeners.get(path).size(), 1, "Should have 1 child-listener on path: " + path);
path = keyBuilder.controller().getPath();
Assert.assertNull(childListeners.get(path), "Should have no child-listener on path: " + path);
// check zookeeper#watches on client side
Map<String, List<String>> watchPaths = ZkTestHelper.getZkWatch(participantToExpire.getZkClient());
LOG.debug("localhost_12918 zk-client side watchPaths: " + watchPaths);
Assert.assertEquals(watchPaths.get("dataWatches").size(), 3, "Should have 3 data-watches: CURRENTSTATE/{sessionId}, CURRENTSTATE/{sessionId}/TestDB, MESSAGES");
Assert.assertEquals(watchPaths.get("childWatches").size(), 2, "Should have 2 child-watches: MESSAGES, and CURRENTSTATE/{sessionId}");
// expire localhost_12918
System.out.println("Expire participant: " + participantToExpire.getInstanceName() + ", session: " + participantToExpire.getSessionId());
ZkTestHelper.expireSession(participantToExpire.getZkClient());
String newSessionId = participantToExpire.getSessionId();
System.out.println(participantToExpire.getInstanceName() + " oldSessionId: " + oldSessionId + ", newSessionId: " + newSessionId);
Assert.assertTrue(verifier.verify());
// check manager#hanlders
Assert.assertEquals(participantToExpire.getHandlers().size(), 1, "Should have 1 handler: MESSAGES. CURRENTSTATE/{sessionId} handler should be removed by CallbackHandler#handleChildChange()");
// check zkclient#listeners
dataListeners = ZkTestHelper.getZkDataListener(participantToExpire.getZkClient());
childListeners = ZkTestHelper.getZkChildListener(participantToExpire.getZkClient());
// printZkListeners(participantToExpire.getZkClient());
Assert.assertTrue(dataListeners.isEmpty(), "Should have no data-listeners");
Assert.assertEquals(childListeners.size(), 2, "Should have 2 paths (CURRENTSTATE/{oldSessionId}, and MESSAGES). " + "MESSAGE has 1 child-listener each. CURRENTSTATE/{oldSessionId} doesn't have listener (ZkClient doesn't remove empty childListener set. probably a ZkClient bug. see ZkClient#unsubscribeChildChange())");
path = keyBuilder.currentStates(participantToExpire.getInstanceName(), oldSessionId).getPath();
Assert.assertEquals(childListeners.get(path).size(), 0, "Should have no child-listener on path: " + path);
path = keyBuilder.messages(participantToExpire.getInstanceName()).getPath();
Assert.assertEquals(childListeners.get(path).size(), 1, "Should have 1 child-listener on path: " + path);
path = keyBuilder.controller().getPath();
Assert.assertNull(childListeners.get(path), "Should have no child-listener on path: " + path);
// check zookeeper#watches on client side
watchPaths = ZkTestHelper.getZkWatch(participantToExpire.getZkClient());
LOG.debug("localhost_12918 zk-client side watchPaths: " + watchPaths);
Assert.assertEquals(watchPaths.get("dataWatches").size(), 1, "Should have 1 data-watch: MESSAGES");
Assert.assertEquals(watchPaths.get("childWatches").size(), 1, "Should have 1 child-watch: MESSAGES");
Assert.assertEquals(watchPaths.get("existWatches").size(), 2, "Should have 2 exist-watches: CURRENTSTATE/{oldSessionId} and CURRENTSTATE/{oldSessionId}/TestDB0");
// another session expiry on localhost_12918 should clear the two exist-watches on
// CURRENTSTATE/{oldSessionId}
System.out.println("Expire participant: " + participantToExpire.getInstanceName() + ", session: " + participantToExpire.getSessionId());
ZkTestHelper.expireSession(participantToExpire.getZkClient());
Assert.assertTrue(verifier.verify());
// check zookeeper#watches on client side
watchPaths = ZkTestHelper.getZkWatch(participantToExpire.getZkClient());
LOG.debug("localhost_12918 zk-client side watchPaths: " + watchPaths);
Assert.assertEquals(watchPaths.get("dataWatches").size(), 1, "Should have 1 data-watch: MESSAGES");
Assert.assertEquals(watchPaths.get("childWatches").size(), 1, "Should have 1 child-watch: MESSAGES");
Assert.assertEquals(watchPaths.get("existWatches").size(), 0, "Should have no exist-watches. exist-watches on CURRENTSTATE/{oldSessionId} and CURRENTSTATE/{oldSessionId}/TestDB0 should be cleared during handleNewSession");
// Thread.sleep(1000);
System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
use of org.apache.helix.NotificationContext in project helix by apache.
the class ServiceDiscovery method setupWatcher.
private void setupWatcher() throws Exception {
LiveInstanceChangeListener listener = new LiveInstanceChangeListener() {
@Override
public void onLiveInstanceChange(List<LiveInstance> liveInstances, NotificationContext changeContext) {
if (changeContext.getType() != NotificationContext.Type.FINALIZE) {
refreshCache();
}
}
};
admin.addLiveInstanceChangeListener(listener);
}
Aggregations