Java Code Examples for org.apache.helix.model.Message#getResourceName()

The following examples show how to use org.apache.helix.model.Message#getResourceName() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SegmentOnlineOfflineStateModelFactory.java    From incubator-pinot with Apache License 2.0 6 votes vote down vote up
@Transition(from = "OFFLINE", to = "DROPPED")
public void onBecomeDroppedFromOffline(Message message, NotificationContext context) {
  _logger.info("SegmentOnlineOfflineStateModel.onBecomeDroppedFromOffline() : " + message);
  String tableNameWithType = message.getResourceName();
  String segmentName = message.getPartitionName();

  // This method might modify the file on disk. Use segment lock to prevent race condition
  Lock segmentLock = SegmentLocks.getSegmentLock(tableNameWithType, segmentName);
  try {
    segmentLock.lock();

    final File segmentDir = new File(_fetcherAndLoader.getSegmentLocalDirectory(tableNameWithType, segmentName));
    if (segmentDir.exists()) {
      FileUtils.deleteQuietly(segmentDir);
      _logger.info("Deleted segment directory {}", segmentDir);
    }
  } catch (final Exception e) {
    _logger.error("Cannot delete the segment : " + segmentName + " from local directory!\n" + e.getMessage(), e);
    Utils.rethrowException(e);
  } finally {
    segmentLock.unlock();
  }
}
 
Example 2
Source File: HelixTaskExecutor.java    From helix with Apache License 2.0 6 votes vote down vote up
/**
 * Find the executor service for the message. A message can have a per-statemodelfactory
 * executor service, or per-message type executor service.
 */
ExecutorService findExecutorServiceForMsg(Message message) {
  ExecutorService executorService = _executorMap.get(message.getMsgType());
  if (message.getMsgType().equals(MessageType.STATE_TRANSITION.name())) {
    if(message.getBatchMessageMode() == true) {
      executorService = _batchMessageExecutorService;
    } else {
      String resourceName = message.getResourceName();
      if (resourceName != null) {
        String key = getPerResourceStateTransitionPoolName(resourceName);
        String perStateTransitionTypeKey =
            getStateTransitionType(key, message.getFromState(), message.getToState());
        if (perStateTransitionTypeKey != null && _executorMap.containsKey(perStateTransitionTypeKey)) {
          LOG.info(String.format("Find per state transition type thread pool for resource %s from %s to %s",
              message.getResourceName(), message.getFromState(), message.getToState()));
          executorService = _executorMap.get(perStateTransitionTypeKey);
        } else if (_executorMap.containsKey(key)) {
          LOG.info("Find per-resource thread pool with key: " + key);
          executorService = _executorMap.get(key);
        }
      }
    }
  }
  return executorService;
}
 
Example 3
Source File: SegmentOnlineOfflineStateModelFactory.java    From incubator-pinot with Apache License 2.0 6 votes vote down vote up
@Transition(from = "OFFLINE", to = "ONLINE")
public void onBecomeOnlineFromOffline(Message message, NotificationContext context) {
  _logger.info("SegmentOnlineOfflineStateModel.onBecomeOnlineFromOffline() : " + message);
  String tableNameWithType = message.getResourceName();
  String segmentName = message.getPartitionName();
  try {
    TableType tableType = TableNameBuilder.getTableTypeFromTableName(message.getResourceName());
    Preconditions.checkNotNull(tableType);
    if (tableType == TableType.OFFLINE) {
      _fetcherAndLoader.addOrReplaceOfflineSegment(tableNameWithType, segmentName);
    } else {
      _instanceDataManager.addRealtimeSegment(tableNameWithType, segmentName);
    }
  } catch (Exception e) {
    _logger.error("Caught exception in state transition from OFFLINE -> ONLINE for resource: {}, partition: {}",
        tableNameWithType, segmentName, e);
    Utils.rethrowException(e);
  }
}
 
Example 4
Source File: TaskStateModel.java    From helix with Apache License 2.0 6 votes vote down vote up
@Transition(to = "ONLINE", from = "OFFLINE")
public void onBecomeOnlineFromOffline(Message message, NotificationContext context)
    throws Exception {
  LOG.debug(_workerId + " becomes ONLINE from OFFLINE for " + _partition);
  ConfigAccessor clusterConfig = context.getManager().getConfigAccessor();
  HelixManager manager = context.getManager();
  HelixConfigScope clusterScope =
      new HelixConfigScopeBuilder(ConfigScopeProperty.CLUSTER).forCluster(
          manager.getClusterName()).build();
  String json = clusterConfig.get(clusterScope, message.getResourceName());
  Dag.Node node = Dag.Node.fromJson(json);
  Set<String> parentIds = node.getParentIds();
  String resourceName = message.getResourceName();
  int numPartitions = node.getNumPartitions();
  Task task = _taskFactory.createTask(resourceName, parentIds, manager, _taskResultStore);
  manager.addExternalViewChangeListener(task);

  LOG.debug("Starting task for " + _partition + "...");
  int partitionNum = Integer.parseInt(_partition.split("_")[1]);
  task.execute(resourceName, numPartitions, partitionNum);
  LOG.debug("Task for " + _partition + " done");
}
 
Example 5
Source File: TestP2PSingleTopState.java    From helix with Apache License 2.0 5 votes vote down vote up
public void doTransition(Message message, NotificationContext context) {
  String to = message.getToState();
  String resource = message.getResourceName();
  String partition = message.getPartitionName();
  String key = resource + "." + partition;

  if (to.equals(MasterSlaveSMD.States.MASTER.name())) {
    Map<String, String> mapFields = new HashMap<>(ExternalViews.get(key));
    if (mapFields.values().contains(MasterSlaveSMD.States.MASTER.name())) {
      Map<String, String> newMapFile = new HashMap<>(mapFields);
      newMapFile.put(_instanceName, to);
      duplicatedPartitionsSnapshot.put(key, newMapFile);
    }

    totalToMaster.incrementAndGet();
    if (message.isRelayMessage()) {
      totalRelayMessage.incrementAndGet();
    }
  }

  ExternalViews.putIfAbsent(key, new ConcurrentHashMap<>());
  if (to.equalsIgnoreCase("DROPPED")) {
    ExternalViews.get(key).remove(_instanceName);
  } else {
    ExternalViews.get(key).put(_instanceName, to);
  }
}
 
Example 6
Source File: SegmentMessageHandlerFactory.java    From incubator-pinot with Apache License 2.0 5 votes vote down vote up
DefaultMessageHandler(Message message, ServerMetrics metrics, NotificationContext context) {
  super(message, context);
  _segmentName = message.getPartitionName();
  _tableNameWithType = message.getResourceName();
  _metrics = metrics;
  _logger = LoggerFactory.getLogger(_tableNameWithType + "-" + this.getClass().getSimpleName());
}
 
Example 7
Source File: SegmentOnlineOfflineStateModelFactory.java    From incubator-pinot with Apache License 2.0 5 votes vote down vote up
@Transition(from = "ONLINE", to = "OFFLINE")
public void onBecomeOfflineFromOnline(Message message, NotificationContext context) {
  _logger.info("SegmentOnlineOfflineStateModel.onBecomeOfflineFromOnline() : " + message);
  String tableNameWithType = message.getResourceName();
  String segmentName = message.getPartitionName();
  try {
    _instanceDataManager.removeSegment(tableNameWithType, segmentName);
  } catch (Exception e) {
    _logger.error("Caught exception in state transition from ONLINE -> OFFLINE for resource: {}, partition: {}",
        tableNameWithType, segmentName, e);
    Utils.rethrowException(e);
  }
}
 
Example 8
Source File: SegmentOnlineOfflineStateModelFactory.java    From incubator-pinot with Apache License 2.0 5 votes vote down vote up
@Transition(from = "CONSUMING", to = "OFFLINE")
public void onBecomeOfflineFromConsuming(Message message, NotificationContext context) {
  _logger.info("SegmentOnlineOfflineStateModel.onBecomeOfflineFromConsuming() : " + message);
  String realtimeTableName = message.getResourceName();
  String segmentName = message.getPartitionName();
  try {
    _instanceDataManager.removeSegment(realtimeTableName, segmentName);
  } catch (Exception e) {
    _logger.error("Caught exception in state transition from CONSUMING -> OFFLINE for resource: {}, partition: {}",
        realtimeTableName, segmentName, e);
    Utils.rethrowException(e);
  }
}
 
Example 9
Source File: SegmentOnlineOfflineStateModelFactory.java    From incubator-pinot with Apache License 2.0 5 votes vote down vote up
@Transition(from = "CONSUMING", to = "ONLINE")
public void onBecomeOnlineFromConsuming(Message message, NotificationContext context) {
  String realtimeTableName = message.getResourceName();
  String segmentNameStr = message.getPartitionName();
  LLCSegmentName segmentName = new LLCSegmentName(segmentNameStr);

  TableDataManager tableDataManager = _instanceDataManager.getTableDataManager(realtimeTableName);
  Preconditions.checkNotNull(tableDataManager);
  SegmentDataManager acquiredSegment = tableDataManager.acquireSegment(segmentNameStr);
  // For this transition to be correct in helix, we should already have a segment that is consuming
  if (acquiredSegment == null) {
    throw new RuntimeException("Segment " + segmentNameStr + " + not present ");
  }

  try {
    if (!(acquiredSegment instanceof LLRealtimeSegmentDataManager)) {
      // We found a LLC segment that is not consuming right now, must be that we already swapped it with a
      // segment that has been built. Nothing to do for this state transition.
      _logger
          .info("Segment {} not an instance of LLRealtimeSegmentDataManager. Reporting success for the transition",
              acquiredSegment.getSegmentName());
      return;
    }
    LLRealtimeSegmentDataManager segmentDataManager = (LLRealtimeSegmentDataManager) acquiredSegment;
    RealtimeSegmentZKMetadata metadata = ZKMetadataProvider
        .getRealtimeSegmentZKMetadata(_instanceDataManager.getPropertyStore(), segmentName.getTableName(),
            segmentNameStr);
    segmentDataManager.goOnlineFromConsuming(metadata);
  } catch (InterruptedException e) {
    _logger.warn("State transition interrupted", e);
    throw new RuntimeException(e);
  } finally {
    tableDataManager.releaseSegment(acquiredSegment);
  }
}
 
Example 10
Source File: StatusUpdateUtil.java    From helix with Apache License 2.0 5 votes vote down vote up
/**
 * Generate the sub-path under STATUSUPDATE or ERROR path for a status update
 */
String getStatusUpdateSubPath(Message message) {
  if (message.getMsgType().equalsIgnoreCase(MessageType.STATE_TRANSITION.name())) {
    return message.getResourceName();
  }
  return message.getMsgType();
}
 
Example 11
Source File: HelixTask.java    From helix with Apache License 2.0 5 votes vote down vote up
private void reportMessageStat(HelixManager manager, Message message, HelixTaskResult taskResult) {
  // report stat
  if (!message.getMsgType().equals(MessageType.STATE_TRANSITION.name())) {
    return;
  }
  long now = new Date().getTime();
  long msgReadTime = message.getReadTimeStamp();
  long msgExecutionStartTime = message.getExecuteStartTimeStamp();
  if (msgReadTime != 0 && msgExecutionStartTime != 0) {
    long totalDelay = now - msgReadTime;
    long executionDelay = now - msgExecutionStartTime;
    long msgLatency = msgReadTime - message.getCreateTimeStamp();
    if (totalDelay >= 0 && executionDelay >= 0) {
      String fromState = message.getFromState();
      String toState = message.getToState();
      String transition = fromState + "--" + toState;

      StateTransitionContext cxt =
          new StateTransitionContext(manager.getClusterName(), manager.getInstanceName(),
              message.getResourceName(), transition);

      StateTransitionDataPoint data =
          new StateTransitionDataPoint(totalDelay, executionDelay, msgLatency,
              taskResult.isSuccess());
      _executor.getParticipantMonitor().reportTransitionStat(cxt, data);
    }
  } else {
    logger.warn(
        "message read time and start execution time not recorded. State transition delay time is not available, message read time {}, Execute start time {}.",
        msgReadTime, msgExecutionStartTime);
  }
}
 
Example 12
Source File: HelixStateMachineEngine.java    From helix with Apache License 2.0 4 votes vote down vote up
@Override
public MessageHandler createHandler(Message message, NotificationContext context) {
  String type = message.getMsgType();

  if (!type.equals(MessageType.STATE_TRANSITION.name()) && !type
      .equals(MessageType.STATE_TRANSITION_CANCELLATION.name())) {
    throw new HelixException("Expect state-transition message type, but was "
        + message.getMsgType() + ", msgId: " + message.getMsgId());
  }

  String partitionKey = message.getPartitionName();
  String stateModelName = message.getStateModelDef();
  String resourceName = message.getResourceName();
  String sessionId = message.getTgtSessionId();
  int bucketSize = message.getBucketSize();

  if (stateModelName == null) {
    logger
        .error("Fail to create msg-handler because message does not contain stateModelDef. msgId: "
            + message.getId());
    return null;
  }

  String factoryName = message.getStateModelFactoryName();
  if (factoryName == null) {
    factoryName = HelixConstants.DEFAULT_STATE_MODEL_FACTORY;
  }

  StateModelFactory<? extends StateModel> stateModelFactory =
      getStateModelFactory(stateModelName, factoryName);
  if (stateModelFactory == null) {
    logger.warn("Fail to create msg-handler because cannot find stateModelFactory for model: "
        + stateModelName + " using factoryName: " + factoryName + " for resource: "
        + resourceName);
    return null;
  }

  // check if the state model definition exists and cache it
  if (!_stateModelDefs.containsKey(stateModelName)) {
    HelixDataAccessor accessor = _manager.getHelixDataAccessor();
    Builder keyBuilder = accessor.keyBuilder();
    StateModelDefinition stateModelDef =
        accessor.getProperty(keyBuilder.stateModelDef(stateModelName));
    if (stateModelDef == null) {
      throw new HelixException("fail to create msg-handler because stateModelDef for "
          + stateModelName + " does NOT exist");
    }
    _stateModelDefs.put(stateModelName, stateModelDef);
  }

  if (!message.getBatchMessageMode()) {
    String initState = _stateModelDefs.get(message.getStateModelDef()).getInitialState();
    StateModel stateModel = stateModelFactory.getStateModel(resourceName, partitionKey);
    if (stateModel == null) {
      stateModel = stateModelFactory.createAndAddStateModel(resourceName, partitionKey);
      if (stateModelName.equals(TaskConstants.STATE_MODEL_NAME)
          && message.getToState().equals(TaskPartitionState.DROPPED.name())) {
        // If stateModel is null, that means there was a reboot of the Participant. Then the
        // purpose of this first message must be to drop the task. We manually set the current
        // state to be the same state of fromState (which Controller inferred from JobContext) to
        // allow the Participant to successfully process this dropping transition
        stateModel.updateState(message.getFromState());
      } else {
        stateModel.updateState(initState);
      }
    }
    if (message.getMsgType().equals(MessageType.STATE_TRANSITION_CANCELLATION.name())) {
      return new HelixStateTransitionCancellationHandler(stateModel, message, context);
    } else {
      // create currentStateDelta for this partition
      // TODO: move currentStateDelta to StateTransitionMsgHandler
      CurrentState currentStateDelta = new CurrentState(resourceName);
      currentStateDelta.setSessionId(sessionId);
      currentStateDelta.setStateModelDefRef(stateModelName);
      currentStateDelta.setStateModelFactoryName(factoryName);
      currentStateDelta.setBucketSize(bucketSize);

      currentStateDelta.setState(partitionKey,
          (stateModel.getCurrentState() == null) ? initState : stateModel.getCurrentState());

      return new HelixStateTransitionHandler(stateModelFactory, stateModel, message, context,
          currentStateDelta);
    }
  } else {
    BatchMessageWrapper wrapper = stateModelFactory.getBatchMessageWrapper(resourceName);
    if (wrapper == null) {
      wrapper = stateModelFactory.createAndAddBatchMessageWrapper(resourceName);
    }

    // get executor-service for the message
    TaskExecutor executor = (TaskExecutor) context.get(MapKey.TASK_EXECUTOR.toString());
    if (executor == null) {
      logger.error(
          "fail to get executor-service for batch message: " + message.getId() + ". msgType: "
              + message.getMsgType() + ", resource: " + message.getResourceName());
      return null;
    }
    return new BatchMessageHandler(message, context, this, wrapper, executor);
  }
}
 
Example 13
Source File: MockHelixTaskExecutor.java    From helix with Apache License 2.0 4 votes vote down vote up
void checkDuplicatedMessages(List<Message> messages) {
  HelixDataAccessor accessor = manager.getHelixDataAccessor();
  PropertyKey.Builder keyBuilder = accessor.keyBuilder();
  PropertyKey path = keyBuilder.currentStates(manager.getInstanceName(), manager.getSessionId());
  Map<String, CurrentState> currentStateMap = accessor.getChildValuesMap(path, true);

  Set<String> seenPartitions = new HashSet<>();
  for (Message message : messages) {
    if (message.getMsgType().equals(Message.MessageType.STATE_TRANSITION.name())) {
      String resource = message.getResourceName();
      String partition = message.getPartitionName();

      //System.err.println(message.getMsgId());
      String key = resource + "-" + partition;
      if (seenPartitions.contains(key)) {
        //System.err.println("Duplicated message received for " + resource + ":" + partition);
        duplicatedMessages++;
      }
      seenPartitions.add(key);

      String toState = message.getToState();
      String state = null;
      if (currentStateMap.containsKey(resource)) {
        CurrentState currentState = currentStateMap.get(resource);
        state = currentState.getState(partition);
      }

      if (toState.equals(state) && message.getMsgState() == Message.MessageState.NEW) {
        //            logger.error(
        //                "Extra message: " + message.getMsgId() + ", Partition is already in target state "
        //                    + toState + " for " + resource + ":" + partition);
        extraStateTransition++;
      }

      String messageTarget =
          getMessageTarget(message.getResourceName(), message.getPartitionName());

      if (message.getMsgState() == Message.MessageState.NEW &&
          _messageTaskMap.containsKey(messageTarget)) {
        String taskId = _messageTaskMap.get(messageTarget);
        MessageTaskInfo messageTaskInfo = _taskMap.get(taskId);
        Message existingMsg = messageTaskInfo.getTask().getMessage();
        if (existingMsg.getMsgId() != message.getMsgId())
          //            logger.error("Duplicated message In Progress: " + message.getMsgId()
          //                    + ", state transition in progress with message " + existingMsg.getMsgId()
          //                    + " to " + toState + " for " + resource + ":" + partition);
          duplicatedMessagesInProgress ++;
      }
    }
  }
}
 
Example 14
Source File: TaskStateModel.java    From helix with Apache License 2.0 4 votes vote down vote up
private void startTask(Message msg, String taskPartition) {
  JobConfig cfg = TaskUtil.getJobConfig(_manager, msg.getResourceName());
  TaskConfig taskConfig = null;
  String command = cfg.getCommand();

  // Get a task-specific command if specified
  JobContext ctx = TaskUtil.getJobContext(_manager, msg.getResourceName());
  int pId = Integer.parseInt(taskPartition.substring(taskPartition.lastIndexOf('_') + 1));
  if (ctx.getTaskIdForPartition(pId) != null) {
    taskConfig = cfg.getTaskConfig(ctx.getTaskIdForPartition(pId));
    if (taskConfig != null) {
      if (taskConfig.getCommand() != null) {
        command = taskConfig.getCommand();
      }
    }
  }

  // Report a target if that was used to assign the partition
  String target = ctx.getTargetForPartition(pId);
  if (taskConfig == null && target != null) {
    taskConfig = TaskConfig.Builder.from(target);
  }

  // Populate a task callback context
  TaskCallbackContext callbackContext = new TaskCallbackContext();
  callbackContext.setManager(_manager);
  callbackContext.setJobConfig(cfg);
  callbackContext.setTaskConfig(taskConfig);

  // Create a task instance with this command
  if (command == null || _taskFactoryRegistry == null
      || !_taskFactoryRegistry.containsKey(command)) {
    throw new IllegalStateException("No callback implemented(or not registered) for task " + command);
  }
  TaskFactory taskFactory = _taskFactoryRegistry.get(command);
  Task task = taskFactory.createNewTask(callbackContext);

  if (task instanceof UserContentStore) {
    ((UserContentStore) task).init(_manager, cfg.getWorkflow(), msg.getResourceName(), taskPartition);
  }

  // Submit the task for execution
  _taskRunner =
      new TaskRunner(task, msg.getResourceName(), taskPartition, msg.getTgtName(), _manager,
          msg.getTgtSessionId());
  _taskExecutor.submit(_taskRunner);
  _taskRunner.waitTillStarted();

  // Set up a timer to cancel the task when its time out expires.

  timeout_task = _timeoutTaskExecutor.schedule(new TimerTask() {
    @Override
    public void run() {
      if (_taskRunner != null) {
        _taskRunner.timeout();
      }
    }
  }, cfg.getTimeoutPerTask(), TimeUnit.MILLISECONDS);
}
 
Example 15
Source File: InstanceMessagesCache.java    From helix with Apache License 2.0 4 votes vote down vote up
private void checkRelayHost(Message relayMessage, Map<String, LiveInstance> liveInstanceMap,
    Map<String, Map<String, Map<String, CurrentState>>> currentStateMap, Message hostedMessage) {

  long currentTime = System.currentTimeMillis();

  String sessionId = hostedMessage.getTgtSessionId();
  String relayInstance = hostedMessage.getTgtName();
  String resourceName = hostedMessage.getResourceName();
  String partitionName = hostedMessage.getPartitionName();

  if (!liveInstanceMap.containsKey(relayInstance)) {
    // If the p2p forwarding host is no longer live, we should not remove the relay message immediately
    // since we do not know whether the relay message was forwarded before the instance went offline.
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }
  String instanceSessionId = liveInstanceMap.get(relayInstance).getEphemeralOwner();
  if (!instanceSessionId.equals(sessionId)) {
    LOG.info("Relay instance sessionId {} does not match sessionId {} in hosted message {}, "
            + "set relay message {} to be expired.", instanceSessionId, sessionId,
        relayMessage.getId(), hostedMessage.getMsgId());
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }

  Map<String, Map<String, CurrentState>> instanceCurrentStateMap =
      currentStateMap.get(relayInstance);
  if (instanceCurrentStateMap == null || !instanceCurrentStateMap.containsKey(sessionId)) {
    LOG.warn(
        "CurrentStateMap null for {}, session {}, set relay messages {} to be expired. Hosted message {}.",
        relayInstance, sessionId, relayMessage.getId(), hostedMessage.getId());
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }

  Map<String, CurrentState> sessionCurrentStateMap = instanceCurrentStateMap.get(sessionId);
  CurrentState currentState = sessionCurrentStateMap.get(resourceName);

  if (currentState == null) {
    LOG.info("No currentState found for {} on {}, set relay message {} to be expired.",
        resourceName, relayInstance, relayMessage.getId());
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }

  String partitionState = currentState.getState(partitionName);
  String targetState = hostedMessage.getToState();
  String fromState = hostedMessage.getFromState();

  // The relay host partition state has been changed after relay message was created.
  if (!fromState.equals(partitionState)) {
    // If the partition on the relay host turned to ERROR while transited from top state,
    // we can remove the cached relay message right away since participant won't forward the relay message anyway.
    if (HelixDefinedState.ERROR.name().equals(partitionState) && fromState
        .equals(currentState.getPreviousState(partitionName))) {
      LOG.info("Partition {} got to ERROR from the top state, "
              + "expiring relay message {} immediately. Hosted message {}.", partitionName,
          relayMessage.getId(), hostedMessage.getId());
      relayMessage.setExpired(true);
      return;
    }

    // If the partition completed the transition, set the relay time to be the actual time when state transition completed.
    if (targetState.equals(partitionState) && fromState
        .equals(currentState.getPreviousState(partitionName))) {
      // The relay host already completed the state transition.
      long completeTime = currentState.getEndTime(partitionName);
      if (completeTime > relayMessage.getCreateTimeStamp()) {
        setMessageRelayTime(relayMessage, completeTime);
        LOG.error("Target state for partition {} matches the hosted message's target state, "
            + "set relay message {} to be expired.", partitionName, relayMessage.getId());
        return;
      }
    }

    // For all other situations, set relay time to be current time.
    setMessageRelayTime(relayMessage, currentTime);
    // the state has been changed after it completed the required state transition (maybe another state-transition happened).
    LOG.info("Current state {} for partition {} does not match hosted message's from state, "
            + "set relay message {} to be expired.", partitionState, partitionName,
        relayMessage.getId());
  }
}
 
Example 16
Source File: InstanceMessagesCache.java    From helix with Apache License 2.0 4 votes vote down vote up
private void checkTargetHost(String targetHost, Message relayMessage, Map<String, LiveInstance> liveInstanceMap,
    Map<String, Map<String, Map<String, CurrentState>>> currentStateMap) {

  long currentTime = System.currentTimeMillis();
  String resourceName = relayMessage.getResourceName();
  String partitionName = relayMessage.getPartitionName();
  String sessionId = relayMessage.getTgtSessionId();

  if (!liveInstanceMap.containsKey(targetHost)) {
    LOG.info("Target host is not alive anymore, expiring relay message {} immediately.",
        relayMessage.getId());
    relayMessage.setExpired(true);
    return;
  }

  String instanceSessionId = liveInstanceMap.get(targetHost).getEphemeralOwner();

  // Target host's session has been changed, remove relay message
  if (!instanceSessionId.equals(sessionId)) {
    LOG.info("Instance SessionId does not match, expiring relay message {} immediately.",
        relayMessage.getId());
    relayMessage.setExpired(true);
    return;
  }

  Map<String, Map<String, CurrentState>> instanceCurrentStateMap =
      currentStateMap.get(targetHost);
  if (instanceCurrentStateMap == null || !instanceCurrentStateMap.containsKey(sessionId)) {
    // This should happen only when a new session is being established.
    // We should not do anything here, once new session is established in participant side,
    // the relay message will be deleted from cache in controller's next pipeline.
    LOG.warn("CurrentStateMap null for {}, session {}, pending relay message {}", targetHost,
        sessionId, relayMessage.getId());
    return;
  }

  Map<String, CurrentState> sessionCurrentStateMap = instanceCurrentStateMap.get(sessionId);
  CurrentState currentState = sessionCurrentStateMap.get(resourceName);
  // TODO: we should add transaction id for each state transition, we can immediately delete the relay message once we have transaction id record in each currentState.
  if (currentState == null) {
    setMessageRelayTime(relayMessage, currentTime);
    LOG.warn("CurrentState is null for {} on {}, set relay time {} for message {}", resourceName,
        targetHost, relayMessage.getRelayTime(), relayMessage.getId());
    return;
  }

  // if the target partition already completed the state transition,
  // or the current state on the target partition has been changed,
  // Do not remove the message immediately to avoid race-condition,
  // for example, controller may decide to move master to another instance at this time,
  // if it does not aware of a pending relay message, it may end up with two masters.
  // so we only set the relay message to be expired.
  // TODO: we should add transaction id for each state transition, we can immediately delete the relay message once we have transaction id record in each currentState.
  String partitionCurrentState = currentState.getState(partitionName);
  String targetState = relayMessage.getToState();
  String fromState = relayMessage.getFromState();
  if (targetState.equals(partitionCurrentState) || !fromState.equals(partitionCurrentState)) {
    setMessageRelayTime(relayMessage, currentTime);
    LOG.debug("{}'s currentState {} on {} has changed, set relay message {} to be expired.",
        partitionName, partitionCurrentState, targetHost, relayMessage.getId());
  }
}
 
Example 17
Source File: StatusUpdateUtil.java    From helix with Apache License 2.0 4 votes vote down vote up
String getStatusUpdateRecordName(Message message) {
  if (message.getMsgType().equalsIgnoreCase(MessageType.STATE_TRANSITION.name())) {
    return message.getTgtSessionId() + "__" + message.getResourceName();
  }
  return message.getMsgId();
}
 
Example 18
Source File: HelixTaskExecutor.java    From helix with Apache License 2.0 4 votes vote down vote up
/** Dedicated Thread pool can be provided in configuration or by client.
 *  This method is to check it and update the thread pool if necessary.
 */
private void updateStateTransitionMessageThreadPool(Message message, HelixManager manager) {
  if (!message.getMsgType().equals(MessageType.STATE_TRANSITION.name())) {
    return;
  }

  String resourceName = message.getResourceName();
  String factoryName = message.getStateModelFactoryName();
  String stateModelName = message.getStateModelDef();

  if (factoryName == null) {
    factoryName = HelixConstants.DEFAULT_STATE_MODEL_FACTORY;
  }
  StateModelFactory<? extends StateModel> stateModelFactory =
      manager.getStateMachineEngine().getStateModelFactory(stateModelName, factoryName);

  String perStateTransitionTypeKey =
      getStateTransitionType(getPerResourceStateTransitionPoolName(resourceName),
          message.getFromState(), message.getToState());
  if (perStateTransitionTypeKey != null && stateModelFactory != null
      && !_transitionTypeThreadpoolChecked.contains(perStateTransitionTypeKey)) {
    ExecutorService perStateTransitionTypeExecutor = stateModelFactory
        .getExecutorService(resourceName, message.getFromState(), message.getToState());
    _transitionTypeThreadpoolChecked.add(perStateTransitionTypeKey);

    if (perStateTransitionTypeExecutor != null) {
      _executorMap.put(perStateTransitionTypeKey, perStateTransitionTypeExecutor);
      LOG.info(String
          .format("Added client specified dedicate threadpool for resource %s from %s to %s",
              getPerResourceStateTransitionPoolName(resourceName), message.getFromState(),
              message.getToState()));
      return;
    }
  }

  if (!_resourcesThreadpoolChecked.contains(resourceName)) {
    int threadpoolSize = -1;
    ConfigAccessor configAccessor = manager.getConfigAccessor();
    // Changes to this configuration on thread pool size will only take effect after the participant get restarted.
    if (configAccessor != null) {
      HelixConfigScope scope =
          new HelixConfigScopeBuilder(ConfigScopeProperty.RESOURCE)
              .forCluster(manager.getClusterName()).forResource(resourceName).build();

      String threadpoolSizeStr = configAccessor.get(scope, MAX_THREADS);
      try {
        if (threadpoolSizeStr != null) {
          threadpoolSize = Integer.parseInt(threadpoolSizeStr);
        }
      } catch (Exception e) {
        LOG.error(
            "Failed to parse ThreadPoolSize from resourceConfig for resource" + resourceName, e);
      }
    }
    final String key = getPerResourceStateTransitionPoolName(resourceName);
    if (threadpoolSize > 0) {
      _executorMap.put(key, Executors.newFixedThreadPool(threadpoolSize, new ThreadFactory() {
        @Override public Thread newThread(Runnable r) {
          return new Thread(r, "GerenricHelixController-message_handle_" + key);
        }
      }));
      LOG.info("Added dedicate threadpool for resource: " + resourceName + " with size: "
          + threadpoolSize);
    } else {
      // if threadpool is not configured
      // check whether client specifies customized threadpool.
      if (stateModelFactory != null) {
        ExecutorService executor = stateModelFactory.getExecutorService(resourceName);
        if (executor != null) {
          _executorMap.put(key, executor);
          LOG.info("Added client specified dedicate threadpool for resource: " + key);
        }
      } else {
        LOG.error(String.format(
            "Fail to get dedicate threadpool defined in stateModelFactory %s: using factoryName: %s for resource %s. No stateModelFactory was found!",
            stateModelName, factoryName, resourceName));
      }
    }
    _resourcesThreadpoolChecked.add(resourceName);
  }
}