use of backtype.storm.messaging.IConnection in project jstorm by alibaba.
the class RefreshConnections method run.
@Override
public void run() {
try {
synchronized (this) {
Integer recordedVersion = zkCluster.assignment_version(topologyId, this);
boolean isUpdateAssignment = !(recordedVersion != null && recordedVersion.equals(assignmentVersion));
boolean isUpdateSupervisorTimeStamp = false;
Long localAssignmentTS = null;
try {
localAssignmentTS = StormConfig.read_supervisor_topology_timestamp(conf, topologyId);
isUpdateSupervisorTimeStamp = localAssignmentTS > workerData.getAssignmentTs();
} catch (FileNotFoundException e) {
LOG.warn("Failed to read supervisor topology timestamp for " + topologyId + " port=" + workerData.getPort(), e);
}
if (isUpdateAssignment || isUpdateSupervisorTimeStamp) {
LOG.info("update worker data due to changed assignment!!!");
Assignment assignment = zkCluster.assignment_info(topologyId, this);
if (assignment == null) {
String errMsg = "Failed to get assignment of " + topologyId;
LOG.error(errMsg);
// throw new RuntimeException(errMsg);
return;
}
// If so, the outbound task map should be updated accordingly.
if (isUpdateSupervisorTimeStamp) {
try {
if (assignment.getAssignmentType() == AssignmentType.UpdateTopology) {
LOG.info("Get config reload request for " + topologyId);
// If config was updated, notify all tasks
List<TaskShutdownDameon> taskShutdowns = workerData.getShutdownTasks();
Map newConf = StormConfig.read_supervisor_topology_conf(conf, topologyId);
workerData.getStormConf().putAll(newConf);
for (TaskShutdownDameon taskSD : taskShutdowns) {
taskSD.update(newConf);
}
// disable/enable metrics on the fly
workerData.getUpdateListener().update(newConf);
workerData.setAssignmentType(AssignmentType.UpdateTopology);
} else {
Set<Integer> addedTasks = getAddedTasks(assignment);
Set<Integer> removedTasks = getRemovedTasks(assignment);
Set<Integer> updatedTasks = getUpdatedTasks(assignment);
workerData.updateWorkerData(assignment);
workerData.updateKryoSerializer();
shutdownTasks(removedTasks);
createTasks(addedTasks);
updateTasks(updatedTasks);
Set<Integer> tmpOutboundTasks = Worker.worker_output_tasks(workerData);
if (!outboundTasks.equals(tmpOutboundTasks)) {
for (int taskId : tmpOutboundTasks) {
if (!outboundTasks.contains(taskId))
workerData.addOutboundTaskStatusIfAbsent(taskId);
}
for (int taskId : workerData.getOutboundTaskStatus().keySet()) {
if (!tmpOutboundTasks.contains(taskId)) {
workerData.removeOutboundTaskStatus(taskId);
}
}
workerData.setOutboundTasks(tmpOutboundTasks);
outboundTasks = tmpOutboundTasks;
}
workerData.setAssignmentType(AssignmentType.Assign);
}
// the tasks will update the related data.
if (localAssignmentTS != null)
workerData.setAssignmentTs(localAssignmentTS);
} catch (Exception e) {
LOG.warn("Failed to update worker data", e);
}
}
Set<ResourceWorkerSlot> workers = assignment.getWorkers();
if (workers == null) {
String errMsg = "Failed to get worker slots of " + topologyId;
LOG.error(errMsg);
return;
}
workerData.updateWorkerToResource(workers);
Map<Integer, WorkerSlot> taskNodePortTmp = new HashMap<>();
Map<String, String> node = assignment.getNodeHost();
// only reserve outboundTasks
Set<ResourceWorkerSlot> needConnections = new HashSet<>();
Set<Integer> localTasks = new HashSet<>();
Set<Integer> localNodeTasks = new HashSet<>();
if (outboundTasks != null) {
for (ResourceWorkerSlot worker : workers) {
if (supervisorId.equals(worker.getNodeId()))
localNodeTasks.addAll(worker.getTasks());
if (supervisorId.equals(worker.getNodeId()) && worker.getPort() == workerData.getPort())
localTasks.addAll(worker.getTasks());
for (Integer id : worker.getTasks()) {
taskNodePortTmp.put(id, worker);
if (outboundTasks.contains(id)) {
needConnections.add(worker);
}
}
}
}
taskToNodePort.putAll(taskNodePortTmp);
// workerData.setLocalTasks(localTasks);
workerData.setLocalNodeTasks(localNodeTasks);
// get which connection need to be remove or add
Set<WorkerSlot> currentConnections = nodePortToSocket.keySet();
Set<ResourceWorkerSlot> newConnections = new HashSet<>();
Set<WorkerSlot> removeConnections = new HashSet<>();
for (ResourceWorkerSlot nodePort : needConnections) {
if (!currentConnections.contains(nodePort)) {
newConnections.add(nodePort);
}
}
for (WorkerSlot node_port : currentConnections) {
if (!needConnections.contains(node_port)) {
removeConnections.add(node_port);
}
}
// create new connection
for (ResourceWorkerSlot nodePort : newConnections) {
String host = node.get(nodePort.getNodeId());
int port = nodePort.getPort();
IConnection conn = context.connect(topologyId, host, port, workerData.getTaskIds(), nodePort.getTasks());
nodePortToSocket.put(nodePort, conn);
LOG.info("Add connection to " + nodePort);
}
// close useless connection
for (WorkerSlot node_port : removeConnections) {
LOG.info("Remove connection to " + node_port);
nodePortToSocket.remove(node_port).close();
}
}
// check the status of connections to all outbound tasks
boolean allConnectionReady = true;
for (Integer taskId : outboundTasks) {
boolean isConnected = isOutTaskConnected(taskId);
if (!isConnected)
allConnectionReady = isConnected;
workerData.updateOutboundTaskStatus(taskId, isConnected);
}
if (allConnectionReady) {
workerData.getWorkerInitConnectionStatus().getAndSet(allConnectionReady);
}
if (recordedVersion != null)
assignmentVersion = recordedVersion;
}
} catch (Exception e) {
LOG.error("Failed to refresh worker connections", e);
throw new RuntimeException(e);
}
}
use of backtype.storm.messaging.IConnection in project jstorm by alibaba.
the class DrainerCtrlRunable method getConnection.
protected IConnection getConnection(int taskId) {
IConnection conn = null;
WorkerSlot nodePort = taskToNodePort.get(taskId);
if (nodePort == null) {
String errorMsg = "IConnection to " + taskId + " can't be found";
LOG.warn("Internal transfer error: {}", errorMsg);
} else {
conn = nodePortToSocket.get(nodePort);
if (conn == null) {
String errorMsg = "NodePort to" + nodePort + " can't be found";
LOG.warn("Internal transfer error: {}", errorMsg);
}
}
return conn;
}
use of backtype.storm.messaging.IConnection in project jstorm by alibaba.
the class DrainerCtrlRunable method handleEvent.
@Override
public void handleEvent(Object event, boolean endOfBatch) throws Exception {
if (event == null) {
return;
}
ITupleExt tuple = (ITupleExt) event;
int targetTask = tuple.getTargetTaskId();
IConnection conn = getConnection(targetTask);
if (conn != null) {
byte[] tupleMessage = null;
try {
// there might be errors when calling update_topology
tupleMessage = serialize(tuple);
} catch (Throwable e) {
if (Utils.exceptionCauseIsInstanceOf(KryoException.class, e)) {
throw new RuntimeException(e);
} else {
LOG.warn("serialize happened errors!!!", e);
}
}
TaskMessage message = new TaskMessage(TaskMessage.CONTROL_MESSAGE, targetTask, tupleMessage);
conn.sendDirect(message);
}
}
use of backtype.storm.messaging.IConnection in project jstorm by alibaba.
the class WorkerShutdown method shutdown.
@Override
public void shutdown() {
if (shutdown.getAndSet(true)) {
LOG.info("Worker has been shutdown already");
return;
}
// dump worker jstack, jmap info to specific file
if (ConfigExtension.isOutworkerDump(conf))
workerDumpInfoOutput();
// shutdown tasks
List<Future<?>> futures = new ArrayList<>();
for (ShutdownableDameon task : shutdownTasks) {
Future<?> future = flusherPool.submit(task);
futures.add(future);
}
// To be assure all tasks are closed rightly
JStormServerUtils.checkFutures(futures);
if (recvConnection != null) {
recvConnection.close();
}
AsyncLoopRunnable.getShutdown().set(true);
threadPool.shutdown();
flusherPool.shutdown();
try {
flusherPool.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
LOG.error("Failed to shutdown client scheduler", e);
}
// refreshconn, refreshzk, hb, drainer
for (AsyncLoopThread t : threads) {
LOG.info("Begin to shutdown " + t.getThread().getName());
t.cleanup();
JStormUtils.sleepMs(100);
t.interrupt();
// try {
// t.join();
// } catch (InterruptedException e) {
// LOG.error("join thread", e);
// }
LOG.info("Successfully " + t.getThread().getName());
}
// send data to close connection
for (WorkerSlot k : nodePortToSocket.keySet()) {
IConnection value = nodePortToSocket.get(k);
value.close();
}
context.term();
// close ZK client
try {
zkCluster.disconnect();
cluster_state.close();
} catch (Exception e) {
LOG.info("Shutdown error,", e);
}
String clusterMode = StormConfig.cluster_mode(conf);
if (clusterMode.equals("distributed")) {
// Only halt process in distributed mode. Because the worker is a fake process in local mode.
JStormUtils.halt_process(0, "!!!Shutdown!!!");
}
}
use of backtype.storm.messaging.IConnection in project jstorm by alibaba.
the class MkShuffer method isOutboundTaskAvailable.
private boolean isOutboundTaskAvailable(int taskId) {
boolean ret = false;
DisruptorQueue targetQueue = workerData.getInnerTaskTransfer().get(taskId);
if (targetQueue != null) {
float queueLoadRatio = targetQueue.pctFull();
if (queueLoadRatio < loadMark) {
ret = true;
}
} else {
WorkerSlot slot = taskNodePort.get(taskId);
if (slot != null) {
IConnection connection = nodePortToSocket.get(slot);
if (connection != null) {
ret = connection.available(taskId);
}
}
}
if (!ret) {
LOG.debug("taskId:{} is unavailable", taskId);
}
return ret;
}
Aggregations