Search in sources :

Example 1 with NodeInformation

use of net.dempsy.NodeInformation in project Dempsy by Dempsy.

the class ApplicationState method apply.

public ApplicationState apply(final ApplicationState.Update update, final TransportManager tmanager, final NodeStatsCollector statsCollector, final RoutingStrategyManager manager) {
    // apply toDelete first.
    final Set<NodeAddress> toDelete = update.toDelete;
    if (toDelete.size() > 0) {
        // just clear all senders.
        for (final NodeAddress a : toDelete) {
            final Sender s = senders.get(a);
            if (s != null)
                s.stop();
        }
    }
    final Map<NodeAddress, NodeInformation> newCurrent = new HashMap<>();
    // the one's to carry over.
    final Set<NodeInformation> leaveAlone = update.leaveAlone;
    for (final NodeInformation cur : leaveAlone) {
        newCurrent.put(cur.nodeAddress, cur);
    }
    // add new senders
    final Set<NodeInformation> toAdd = update.toAdd;
    for (final NodeInformation cur : toAdd) {
        newCurrent.put(cur.nodeAddress, cur);
    }
    // now flush out the remaining caches.
    // collapse all clusterInfos
    final Set<ClusterInformation> allCis = new HashSet<>();
    newCurrent.values().forEach(ni -> allCis.addAll(ni.clusterInfoByClusterId.values()));
    final Map<String, RoutingStrategy.Router> newOutboundByClusterName = new HashMap<>();
    final Map<String, Set<String>> cnByType = new HashMap<>();
    final Set<String> knownClusterOutbounds = new HashSet<>(outboundByClusterName_.keySet());
    for (final ClusterInformation ci : allCis) {
        final String clusterName = ci.clusterId.clusterName;
        final RoutingStrategy.Router ob = outboundByClusterName_.get(clusterName);
        knownClusterOutbounds.remove(clusterName);
        if (ob != null)
            newOutboundByClusterName.put(clusterName, ob);
        else {
            final RoutingStrategy.Factory obfactory = manager.getAssociatedInstance(ci.routingStrategyTypeId);
            final RoutingStrategy.Router nob = obfactory.getStrategy(ci.clusterId);
            newOutboundByClusterName.put(clusterName, nob);
        }
        // add all of the message types handled.
        ci.messageTypesHandled.forEach(mt -> {
            Set<String> entry = cnByType.get(mt);
            if (entry == null) {
                entry = new HashSet<>();
                cnByType.put(mt, entry);
            }
            entry.add(clusterName);
        });
    }
    return new ApplicationState(newOutboundByClusterName, cnByType, newCurrent, tmanager, thisNode);
}
Also used : NodeInformation(net.dempsy.NodeInformation) Set(java.util.Set) HashSet(java.util.HashSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ClusterInformation(net.dempsy.ClusterInformation) Sender(net.dempsy.transport.Sender) RoutingStrategy(net.dempsy.router.RoutingStrategy) NodeAddress(net.dempsy.transport.NodeAddress) HashSet(java.util.HashSet)

Example 2 with NodeInformation

use of net.dempsy.NodeInformation in project Dempsy by Dempsy.

the class ApplicationState method apply.

public ApplicationState apply(final ApplicationState.Update update, final TransportManager tmanager, final NodeStatsCollector statsCollector, final RoutingStrategyManager manager, final String thisNodeId) {
    // apply toDelete first.
    final Set<NodeAddress> toDelete = update.toDelete;
    final boolean infoEnabled = LOGGER_SESSION.isInfoEnabled();
    if (toDelete.size() > 0) {
        // just clear all senders.
        if (infoEnabled)
            LOGGER_SESSION.info("[{}] Applying update to topology resulting in removing several destinations:", thisNodeId);
        for (final NodeAddress a : toDelete) {
            final Sender s = senders.remove(a);
            if (infoEnabled)
                LOGGER_SESSION.info("[{}]      removing sender ({}) to {}", thisNodeId, s, a);
            if (s != null)
                s.stop();
        }
    }
    final Map<NodeAddress, NodeInformation> newCurrent = new HashMap<>();
    // the one's to carry over.
    final Set<NodeInformation> leaveAlone = update.leaveAlone;
    if (leaveAlone.size() > 0)
        if (infoEnabled)
            LOGGER_SESSION.info("[{}] Applying update to topology resulting in leaving several destinations:", thisNodeId);
    for (final NodeInformation cur : leaveAlone) {
        if (infoEnabled)
            LOGGER_SESSION.info("[{}]      leaving alone : {}", thisNodeId, Optional.ofNullable(cur).map(ni -> ni.nodeAddress).orElse(null));
        newCurrent.put(cur.nodeAddress, cur);
    }
    // add new senders
    final Set<NodeInformation> toAdd = update.toAdd;
    if (toAdd.size() > 0)
        if (infoEnabled)
            LOGGER_SESSION.info("[{}] Applying update to topology resulting in adding several destinations:", thisNodeId);
    for (final NodeInformation cur : toAdd) {
        if (infoEnabled)
            LOGGER_SESSION.info("[{}]      adding : {}", thisNodeId, Optional.ofNullable(cur).map(ni -> ni.nodeAddress).orElse(null));
        newCurrent.put(cur.nodeAddress, cur);
    }
    // now flush out the remaining caches.
    // collapse all clusterInfos
    final Set<ClusterInformation> allCis = new HashSet<>();
    newCurrent.values().forEach(ni -> allCis.addAll(ni.clusterInfoByClusterId.values()));
    final Map<String, RoutingStrategy.Router> newOutboundByClusterName = new HashMap<>();
    final Map<String, Set<String>> cnByType = new HashMap<>();
    final Set<String> knownClusterOutbounds = new HashSet<>(outboundByClusterName_.keySet());
    for (final ClusterInformation ci : allCis) {
        final String clusterName = ci.clusterId.clusterName;
        final RoutingStrategy.Router ob = outboundByClusterName_.get(clusterName);
        knownClusterOutbounds.remove(clusterName);
        if (ob != null)
            newOutboundByClusterName.put(clusterName, ob);
        else {
            final RoutingStrategy.Factory obfactory = manager.getAssociatedInstance(ci.routingStrategyTypeId);
            final RoutingStrategy.Router nob = obfactory.getStrategy(ci.clusterId);
            newOutboundByClusterName.put(clusterName, nob);
        }
        // add all of the message types handled.
        ci.messageTypesHandled.forEach(mt -> {
            Set<String> entry = cnByType.get(mt);
            if (entry == null) {
                entry = new HashSet<>();
                cnByType.put(mt, entry);
            }
            entry.add(clusterName);
        });
    }
    return new ApplicationState(newOutboundByClusterName, cnByType, newCurrent, tmanager, thisNode, senders);
}
Also used : Sender(net.dempsy.transport.Sender) TransportManager(net.dempsy.transport.TransportManager) ClusterInformation(net.dempsy.ClusterInformation) ContainerAddress(net.dempsy.router.RoutingStrategy.ContainerAddress) KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType) NodeAddress(net.dempsy.transport.NodeAddress) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SenderFactory(net.dempsy.transport.SenderFactory) Set(java.util.Set) HashMap(java.util.HashMap) LOGGER(net.dempsy.intern.OutgoingDispatcher.LOGGER) ArrayList(java.util.ArrayList) RoutingStrategyManager(net.dempsy.router.RoutingStrategyManager) HashSet(java.util.HashSet) NodeStatsCollector(net.dempsy.monitoring.NodeStatsCollector) List(java.util.List) RoutingStrategy(net.dempsy.router.RoutingStrategy) Map(java.util.Map) Optional(java.util.Optional) LOGGER_SESSION(net.dempsy.intern.OutgoingDispatcher.LOGGER_SESSION) NodeInformation(net.dempsy.NodeInformation) NodeInformation(net.dempsy.NodeInformation) Set(java.util.Set) HashSet(java.util.HashSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ClusterInformation(net.dempsy.ClusterInformation) Sender(net.dempsy.transport.Sender) RoutingStrategy(net.dempsy.router.RoutingStrategy) NodeAddress(net.dempsy.transport.NodeAddress) HashSet(java.util.HashSet)

Example 3 with NodeInformation

use of net.dempsy.NodeInformation in project Dempsy by Dempsy.

the class ApplicationState method update.

public ApplicationState.Update update(final Set<NodeInformation> newState, final NodeAddress thisNodeX, final String thisNodeId) {
    final Set<NodeInformation> toAdd = new HashSet<>();
    final Set<NodeAddress> toDelete = new HashSet<>();
    final Set<NodeAddress> knownAddr = new HashSet<>(current.keySet());
    final Set<NodeInformation> leaveAlone = new HashSet<>();
    NodeAddress oursOnTheList = null;
    for (final NodeInformation cur : newState) {
        final NodeInformation known = current.get(cur.nodeAddress);
        if (cur.nodeAddress.equals(thisNodeX))
            oursOnTheList = cur.nodeAddress;
        if (// then we don't know about this one yet.
        known == null)
            // we need to add this one
            toAdd.add(cur);
        else {
            if (!known.equals(cur)) {
                // known but changed ... we need to add and delete it
                toAdd.add(cur);
                toDelete.add(known.nodeAddress);
            } else
                leaveAlone.add(known);
            // remove it from the known ones. Whatever is leftover will
            // end up needing to be deleted.
            knownAddr.remove(known.nodeAddress);
        }
    }
    if (// we don't seem to have our own address registered with the collaborator.
    oursOnTheList == null && thisNodeX != null)
        // this condition is actually okay since the Router is started before the
        // node is registered with the collaborator.
        LOGGER_SESSION.trace("Router at {} doesn't seem to have its own address registered with the collaborator yet", thisNodeId);
    // dump the remaining knownAddrs on the toDelete list
    toDelete.addAll(knownAddr);
    return new Update(leaveAlone, toAdd, toDelete);
}
Also used : NodeInformation(net.dempsy.NodeInformation) NodeAddress(net.dempsy.transport.NodeAddress) HashSet(java.util.HashSet)

Example 4 with NodeInformation

use of net.dempsy.NodeInformation in project Dempsy by Dempsy.

the class OutgoingDispatcher method start.

@Override
public void start(final Infrastructure infra) {
    final ClusterInfoSession session = infra.getCollaborator();
    final String nodesDir = infra.getRootPaths().nodesDir;
    checkup = new PersistentTask(LOGGER_SESSION, isRunning, infra.getScheduler(), RETRY_TIMEOUT) {

        @Override
        public boolean execute() {
            try {
                // collect up all NodeInfo's known about.
                session.recursiveMkdir(nodesDir, null, DirMode.PERSISTENT, DirMode.PERSISTENT);
                final Collection<String> nodeDirs = session.getSubdirs(nodesDir, this);
                final Set<NodeInformation> alreadySeen = new HashSet<>();
                // get all of the subdirectories NodeInformations
                for (final String subdir : nodeDirs) {
                    final NodeInformation ni = (NodeInformation) session.getData(nodesDir + "/" + subdir, null);
                    if (ni == null) {
                        LOGGER_SESSION.warn("[{}] A node directory was empty at " + subdir, thisNodeId);
                        return false;
                    }
                    // see if node info is dupped.
                    if (alreadySeen.contains(ni)) {
                        LOGGER_SESSION.warn("[{}] The node " + ni.nodeAddress + " seems to be registed more than once.", thisNodeId);
                        continue;
                    }
                    if (ni.clusterInfoByClusterId.size() == 0) {
                        // it's ALL adaptor so there's no sense in dealing with it
                        LOGGER_SESSION.trace("[{}] NodeInformation {} appears to be only an Adaptor.", thisNodeId, ni);
                        continue;
                    }
                    alreadySeen.add(ni);
                }
                // check to see if there's new nodes.
                final ApplicationState.Update ud = outbounds.get().update(alreadySeen, thisNode, thisNodeId);
                if (!ud.change()) {
                    LOGGER_SESSION.info("[{}] Topology change notification resulted in no changes.", thisNodeId);
                    isReady.set(true);
                    // nothing to update.
                    return true;
                } else if (LOGGER_SESSION.isTraceEnabled())
                    LOGGER_SESSION.info("[{}] Topology change notification resulted in changes ", thisNodeId);
                // otherwise we will be making changes so remove the current ApplicationState
                // this can cause instability.
                final ApplicationState obs = outbounds.getAndSet(null);
                try {
                    final ApplicationState newState = obs.apply(ud, tmanager, statsCollector, manager, thisNodeId);
                    outbounds.set(newState);
                    isReady.set(true);
                    return true;
                } catch (final RuntimeException rte) {
                    // if we threw an exception after clearing the outbounds we need to restore it.
                    // This is likely a configuration error so we should probably warn about it.
                    LOGGER_SESSION.warn("[{}] Unexpected exception while applying a topology update", thisNodeId, rte);
                    outbounds.set(obs);
                    throw rte;
                }
            } catch (final ClusterInfoException e) {
                final String message = "Failed to find outgoing route information. Will retry shortly.";
                if (LOGGER_SESSION.isTraceEnabled())
                    LOGGER_SESSION.debug("[{}] {}", new Object[] { thisNodeId, message, e });
                else
                    LOGGER_SESSION.debug("[{}] {}", thisNodeId, message);
                return false;
            }
        }

        @Override
        public String toString() {
            return thisNodeId + " find nodes to route to";
        }
    };
    outbounds.set(new ApplicationState(tmanager, thisNode, new ConcurrentHashMap<>()));
    isRunning.set(true);
    checkup.process();
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) NodeInformation(net.dempsy.NodeInformation) ClusterInfoException(net.dempsy.cluster.ClusterInfoException) SafeString(net.dempsy.util.SafeString) PersistentTask(net.dempsy.utils.PersistentTask) Collection(java.util.Collection) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

HashSet (java.util.HashSet)4 NodeInformation (net.dempsy.NodeInformation)4 Set (java.util.Set)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 NodeAddress (net.dempsy.transport.NodeAddress)3 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 ClusterInformation (net.dempsy.ClusterInformation)2 RoutingStrategy (net.dempsy.router.RoutingStrategy)2 Sender (net.dempsy.transport.Sender)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 ClusterInfoException (net.dempsy.cluster.ClusterInfoException)1 ClusterInfoSession (net.dempsy.cluster.ClusterInfoSession)1 LOGGER (net.dempsy.intern.OutgoingDispatcher.LOGGER)1 LOGGER_SESSION (net.dempsy.intern.OutgoingDispatcher.LOGGER_SESSION)1 KeyedMessageWithType (net.dempsy.messages.KeyedMessageWithType)1 NodeStatsCollector (net.dempsy.monitoring.NodeStatsCollector)1