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);
}
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);
}
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);
}
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();
}
Aggregations