/** * Factory method for initialize a instance. * @param conf config. * @return an instance of {@link AssignmentDistributionService} */ public static AssignmentDistributionService getInstance(Map conf) { AssignmentDistributionService service = new AssignmentDistributionService(); service.prepare(conf); return service; }
/** * Used for local cluster. * * @param supervisor {@link org.apache.storm.daemon.supervisor.Supervisor} */ public void addSupervisor(org.apache.storm.daemon.supervisor.Supervisor supervisor) { assignmentsDistributer.addLocalSupervisor(supervisor); }
@Override public void run() { while (service.isActive()) { try { NodeAssignments nodeAssignments = this.service.nextAssignments(queueIndex); sendAssignmentsToNode(nodeAssignments); } catch (InterruptedException e) { if (service.isActive()) { LOG.error("Get an unexpected interrupt when distributing assignments to node, {}", e.getCause()); } else { // service is off now just interrupt it. Thread.currentThread().interrupt(); } } } }
/** * Get an assignments from the target queue with the specific index. * @param queueIndex index of the queue * @return an {@link NodeAssignments} * @throws InterruptedException */ public NodeAssignments nextAssignments(Integer queueIndex) throws InterruptedException { NodeAssignments target = null; while (true) { target = getQueueById(queueIndex).poll(); if (target != null) { return target; } Time.sleep(100L); } }
/** * Add an assignments for a node/supervisor for distribution. * @param node node id of supervisor. * @param host host name for the node. * @param serverPort node thrift server port. * @param assignments the {@link org.apache.storm.generated.SupervisorAssignments} */ public void addAssignmentsForNode(String node, String host, Integer serverPort, SupervisorAssignments assignments) { try { //For some reasons, we can not get supervisor port info, eg: supervisor shutdown, //Just skip for this scheduling round. if (serverPort == null) { LOG.warn("Discard an assignment distribution for node {} because server port info is missing.", node); return; } boolean success = nextQueue().offer(NodeAssignments.getInstance(node, host, serverPort, assignments), 5L, TimeUnit.SECONDS); if (!success) { LOG.warn("Discard an assignment distribution for node {} because the target sub queue is full.", node); } } catch (InterruptedException e) { LOG.error("Add node assignments interrupted: {}", e.getMessage()); throw new RuntimeException(e); } }
/** * Notify supervisors/nodes assigned assignments. * * @param assignments assignments map for nodes * @param service {@link AssignmentDistributionService} for distributing assignments asynchronous * @param nodeHost node -> host map * @param supervisorDetails nodeId -> {@link SupervisorDetails} map */ private static void notifySupervisorsAssignments(Map<String, Assignment> assignments, AssignmentDistributionService service, Map<String, String> nodeHost, Map<String, SupervisorDetails> supervisorDetails) { for (Map.Entry<String, String> nodeEntry : nodeHost.entrySet()) { try { String nodeId = nodeEntry.getKey(); SupervisorAssignments supervisorAssignments = new SupervisorAssignments(); supervisorAssignments.set_storm_assignment(assignmentsForNode(assignments, nodeEntry.getKey())); SupervisorDetails details = supervisorDetails.get(nodeId); Integer serverPort = details != null ? details.getServerPort() : null; service.addAssignmentsForNode(nodeId, nodeEntry.getValue(), serverPort, supervisorAssignments); } catch (Throwable tr1) { //just skip when any error happens wait for next round assignments reassign LOG.error("Exception when add assignments distribution task for node {}", nodeEntry.getKey()); } } }
private void sendAssignmentsToNode(NodeAssignments assignments) { if (this.service.isLocalMode) { //local node Supervisor supervisor = this.service.localSupervisors.get(assignments.getNode()); if (supervisor != null) { supervisor.sendSupervisorAssignments(assignments.getAssignments()); } else { LOG.error("Can not find node {} for assignments distribution", assignments.getNode()); throw new RuntimeException("null for node " + assignments.getNode() + " supervisor instance."); } } else { // distributed mode try (SupervisorClient client = SupervisorClient.getConfiguredClient(service.getConf(), assignments.getHost(), assignments.getServerPort())) { try { client.getClient().sendSupervisorAssignments(assignments.getAssignments()); } catch (Exception e) { //just ignore the exception. LOG.error("Exception when trying to send assignments to node {}: {}", assignments.getNode(), e.getMessage()); } } catch (Throwable e) { //just ignore any error/exception. LOG.error("Exception to create supervisor client for node {}: {}", assignments.getNode(), e.getMessage()); } } } }
blobStore.shutdown(); leaderElector.close(); assignmentsDistributer.close(); ITopologyActionNotifierPlugin actionNotifier = nimbusTopologyActionNotifier; if (actionNotifier != null) {
this.assignmentsDistributer = AssignmentDistributionService.getInstance(conf); this.idToSchedStatus = new AtomicReference<>(new HashMap<>()); this.nodeIdToResources = new AtomicReference<>(new HashMap<>());