Search in sources :

Example 6 with Message

use of org.apache.helix.model.Message in project helix by apache.

the class MessageSelectionStage method process.

@Override
public void process(ClusterEvent event) throws Exception {
    ClusterDataCache cache = event.getAttribute(AttributeName.ClusterDataCache.name());
    Map<String, Resource> resourceMap = event.getAttribute(AttributeName.RESOURCES.name());
    CurrentStateOutput currentStateOutput = event.getAttribute(AttributeName.CURRENT_STATE.name());
    MessageGenerationOutput messageGenOutput = event.getAttribute(AttributeName.MESSAGES_ALL.name());
    if (cache == null || resourceMap == null || currentStateOutput == null || messageGenOutput == null) {
        throw new StageException("Missing attributes in event:" + event + ". Requires DataCache|RESOURCES|CURRENT_STATE|MESSAGES_ALL");
    }
    MessageSelectionStageOutput output = new MessageSelectionStageOutput();
    for (String resourceName : resourceMap.keySet()) {
        Resource resource = resourceMap.get(resourceName);
        StateModelDefinition stateModelDef = cache.getStateModelDef(resource.getStateModelDefRef());
        Map<String, Integer> stateTransitionPriorities = getStateTransitionPriorityMap(stateModelDef);
        IdealState idealState = cache.getIdealState(resourceName);
        Map<String, Bounds> stateConstraints = computeStateConstraints(stateModelDef, idealState, cache);
        for (Partition partition : resource.getPartitions()) {
            List<Message> messages = messageGenOutput.getMessages(resourceName, partition);
            List<Message> selectedMessages = selectMessages(cache.getLiveInstances(), currentStateOutput.getCurrentStateMap(resourceName, partition), currentStateOutput.getPendingMessageMap(resourceName, partition), messages, stateConstraints, stateTransitionPriorities, stateModelDef, resource.isP2PMessageEnabled());
            output.addMessages(resourceName, partition, selectedMessages);
        }
    }
    event.addAttribute(AttributeName.MESSAGES_SELECTED.name(), output);
}
Also used : Partition(org.apache.helix.model.Partition) Message(org.apache.helix.model.Message) StageException(org.apache.helix.controller.pipeline.StageException) Resource(org.apache.helix.model.Resource) IdealState(org.apache.helix.model.IdealState) StateModelDefinition(org.apache.helix.model.StateModelDefinition)

Example 7 with Message

use of org.apache.helix.model.Message in project helix by apache.

the class MessageThrottleStage method process.

@Override
public void process(ClusterEvent event) throws Exception {
    ClusterDataCache cache = event.getAttribute(AttributeName.ClusterDataCache.name());
    MessageSelectionStageOutput msgSelectionOutput = event.getAttribute(AttributeName.MESSAGES_SELECTED.name());
    Map<String, Resource> resourceMap = event.getAttribute(AttributeName.RESOURCES.name());
    if (cache == null || resourceMap == null || msgSelectionOutput == null) {
        throw new StageException("Missing attributes in event: " + event + ". Requires ClusterDataCache|RESOURCES|MESSAGES_SELECTED");
    }
    MessageThrottleStageOutput output = new MessageThrottleStageOutput();
    ClusterConstraints constraint = cache.getConstraint(ConstraintType.MESSAGE_CONSTRAINT);
    Map<String, Integer> throttleCounterMap = new HashMap<String, Integer>();
    if (constraint != null) {
        // go through all pending messages, they should be counted but not throttled
        for (String instance : cache.getLiveInstances().keySet()) {
            throttle(throttleCounterMap, constraint, new ArrayList<Message>(cache.getMessages(instance).values()), false);
        }
    }
    // assume messages should be sorted by state transition priority in messageSelection stage
    for (String resourceName : resourceMap.keySet()) {
        Resource resource = resourceMap.get(resourceName);
        for (Partition partition : resource.getPartitions()) {
            List<Message> messages = msgSelectionOutput.getMessages(resourceName, partition);
            if (constraint != null && messages != null && messages.size() > 0) {
                messages = throttle(throttleCounterMap, constraint, messages, true);
            }
            output.addMessages(resourceName, partition, messages);
        }
    }
    event.addAttribute(AttributeName.MESSAGES_THROTTLE.name(), output);
}
Also used : Partition(org.apache.helix.model.Partition) Message(org.apache.helix.model.Message) HashMap(java.util.HashMap) StageException(org.apache.helix.controller.pipeline.StageException) Resource(org.apache.helix.model.Resource) ClusterConstraints(org.apache.helix.model.ClusterConstraints)

Example 8 with Message

use of org.apache.helix.model.Message in project helix by apache.

the class CurrentStateComputationStage method updatePendingMessages.

// update all pending messages to CurrentStateOutput.
private void updatePendingMessages(LiveInstance instance, Collection<Message> pendingMessages, CurrentStateOutput currentStateOutput, Map<String, Resource> resourceMap) {
    String instanceName = instance.getInstanceName();
    String instanceSessionId = instance.getSessionId();
    // update all pending messages
    for (Message message : pendingMessages) {
        if (!MessageType.STATE_TRANSITION.name().equalsIgnoreCase(message.getMsgType()) && !MessageType.STATE_TRANSITION_CANCELLATION.name().equalsIgnoreCase(message.getMsgType())) {
            continue;
        }
        if (!instanceSessionId.equals(message.getTgtSessionId())) {
            continue;
        }
        String resourceName = message.getResourceName();
        Resource resource = resourceMap.get(resourceName);
        if (resource == null) {
            continue;
        }
        if (!message.getBatchMessageMode()) {
            String partitionName = message.getPartitionName();
            Partition partition = resource.getPartition(partitionName);
            if (partition != null) {
                setMessageState(currentStateOutput, resourceName, partition, instanceName, message);
            } else {
            // log
            }
        } else {
            List<String> partitionNames = message.getPartitionNames();
            if (!partitionNames.isEmpty()) {
                for (String partitionName : partitionNames) {
                    Partition partition = resource.getPartition(partitionName);
                    if (partition != null) {
                        setMessageState(currentStateOutput, resourceName, partition, instanceName, message);
                    } else {
                    // log
                    }
                }
            }
        }
    }
}
Also used : Partition(org.apache.helix.model.Partition) Message(org.apache.helix.model.Message) Resource(org.apache.helix.model.Resource)

Example 9 with Message

use of org.apache.helix.model.Message in project helix by apache.

the class InstanceMessagesCache method updateRelayMessages.

// update all valid relay messages attached to existing state transition messages into message map.
public void updateRelayMessages(Map<String, LiveInstance> liveInstanceMap, Map<String, Map<String, Map<String, CurrentState>>> currentStateMap) {
    List<Message> relayMessages = new ArrayList<>();
    for (String instance : _messageMap.keySet()) {
        Map<String, Message> instanceMessages = _messageMap.get(instance);
        Map<String, Map<String, CurrentState>> instanceCurrentStateMap = currentStateMap.get(instance);
        if (instanceCurrentStateMap == null) {
            continue;
        }
        for (Message message : instanceMessages.values()) {
            if (message.hasRelayMessages()) {
                String sessionId = message.getTgtSessionId();
                String resourceName = message.getResourceName();
                String partitionName = message.getPartitionName();
                String targetState = message.getToState();
                String instanceSessionId = liveInstanceMap.get(instance).getSessionId();
                if (!instanceSessionId.equals(sessionId)) {
                    LOG.info("Instance SessionId does not match, ignore relay messages attached to message " + message.getId());
                    continue;
                }
                Map<String, CurrentState> sessionCurrentStateMap = instanceCurrentStateMap.get(sessionId);
                if (sessionCurrentStateMap == null) {
                    LOG.info("No sessionCurrentStateMap found, ignore relay messages attached to message " + message.getId());
                    continue;
                }
                CurrentState currentState = sessionCurrentStateMap.get(resourceName);
                if (currentState == null || !targetState.equals(currentState.getState(partitionName))) {
                    LOG.info("CurrentState " + currentState + " do not match the target state of the message, ignore relay messages attached to message " + message.getId());
                    continue;
                }
                long transitionCompleteTime = currentState.getEndTime(partitionName);
                for (Message relayMsg : message.getRelayMessages().values()) {
                    relayMsg.setRelayTime(transitionCompleteTime);
                    if (!relayMsg.isExpired()) {
                        relayMessages.add(relayMsg);
                    } else {
                        LOG.info("Relay message " + relayMsg.getId() + " already expired, ignore it!");
                    }
                }
            }
        }
    }
    for (Message message : relayMessages) {
        String instance = message.getTgtName();
        Map<String, Message> instanceMessages = _messageMap.get(instance);
        if (instanceMessages == null) {
            instanceMessages = new HashMap<>();
            _messageMap.put(instance, instanceMessages);
        }
        instanceMessages.put(message.getId(), message);
    }
}
Also used : Message(org.apache.helix.model.Message) CurrentState(org.apache.helix.model.CurrentState) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map)

Example 10 with Message

use of org.apache.helix.model.Message in project helix by apache.

the class InstanceMessagesCache method refresh.

/**
 * This refreshes all pending messages in the cluster by re-fetching the data from zookeeper in an
 * efficient way
 * current state must be refreshed before refreshing relay messages because we need to use current
 * state to validate all relay messages.
 *
 * @param accessor
 * @param liveInstanceMap
 *
 * @return
 */
public boolean refresh(HelixDataAccessor accessor, Map<String, LiveInstance> liveInstanceMap) {
    LOG.info("START: InstanceMessagesCache.refresh()");
    long startTime = System.currentTimeMillis();
    PropertyKey.Builder keyBuilder = accessor.keyBuilder();
    Map<String, Map<String, Message>> msgMap = new HashMap<>();
    List<PropertyKey> newMessageKeys = Lists.newLinkedList();
    long purgeSum = 0;
    for (String instanceName : liveInstanceMap.keySet()) {
        // get the cache
        Map<String, Message> cachedMap = _messageCache.get(instanceName);
        if (cachedMap == null) {
            cachedMap = Maps.newHashMap();
            _messageCache.put(instanceName, cachedMap);
        }
        msgMap.put(instanceName, cachedMap);
        // get the current names
        Set<String> messageNames = Sets.newHashSet(accessor.getChildNames(keyBuilder.messages(instanceName)));
        long purgeStart = System.currentTimeMillis();
        // clear stale names
        Iterator<String> cachedNamesIter = cachedMap.keySet().iterator();
        while (cachedNamesIter.hasNext()) {
            String messageName = cachedNamesIter.next();
            if (!messageNames.contains(messageName)) {
                cachedNamesIter.remove();
            }
        }
        long purgeEnd = System.currentTimeMillis();
        purgeSum += purgeEnd - purgeStart;
        // get the keys for the new messages
        for (String messageName : messageNames) {
            if (!cachedMap.containsKey(messageName)) {
                newMessageKeys.add(keyBuilder.message(instanceName, messageName));
            }
        }
    }
    // get the new messages
    if (newMessageKeys.size() > 0) {
        List<Message> newMessages = accessor.getProperty(newMessageKeys, true);
        for (Message message : newMessages) {
            if (message != null) {
                Map<String, Message> cachedMap = _messageCache.get(message.getTgtName());
                cachedMap.put(message.getId(), message);
            }
        }
    }
    _messageMap = Collections.unmodifiableMap(msgMap);
    if (LOG.isDebugEnabled()) {
        LOG.debug("Message purge took: " + purgeSum);
        LOG.debug("# of Messages read from ZooKeeper " + newMessageKeys.size() + ". took " + (System.currentTimeMillis() - startTime) + " ms.");
    }
    return true;
}
Also used : Message(org.apache.helix.model.Message) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map) PropertyKey(org.apache.helix.PropertyKey)

Aggregations

Message (org.apache.helix.model.Message)116 Test (org.testng.annotations.Test)53 ArrayList (java.util.ArrayList)36 HelixDataAccessor (org.apache.helix.HelixDataAccessor)30 Builder (org.apache.helix.PropertyKey.Builder)28 HelixManager (org.apache.helix.HelixManager)22 ZNRecord (org.apache.helix.ZNRecord)22 Criteria (org.apache.helix.Criteria)21 Date (java.util.Date)19 HashMap (java.util.HashMap)18 Partition (org.apache.helix.model.Partition)18 PropertyKey (org.apache.helix.PropertyKey)17 LiveInstance (org.apache.helix.model.LiveInstance)13 ZKHelixDataAccessor (org.apache.helix.manager.zk.ZKHelixDataAccessor)12 NotificationContext (org.apache.helix.NotificationContext)11 CurrentState (org.apache.helix.model.CurrentState)10 HelixException (org.apache.helix.HelixException)9 Resource (org.apache.helix.model.Resource)9 StringWriter (java.io.StringWriter)8 List (java.util.List)8