Commit 4f93e274 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Updated Monitor-API

- dynamic caching and reloading of analyzer-proxies
- extended nodeInfo interface with isActive() method
- extended PubSubForwardingAnalyzer
parent 016e363e
......@@ -24,6 +24,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
......@@ -51,7 +52,7 @@ public final class Monitor {
private static Map<Class<?>, Boolean> cachedCheck = new LinkedHashMap<>();
private static boolean invalidCache = true;
private static List<Delegator<?>> delegators = new LinkedList<>();
private static MonitorComponent getMonitor() {
if (monitor == null) {
......@@ -103,7 +104,7 @@ public final class Monitor {
/**
* Retrieve an analyzing-Interface (transparent multiplexing is performed,
* if multiple analyzers with the same interface are registered)
* if multiple analyzers with the same interface are registered).
*
* @param analyzerType
* @return
......@@ -116,16 +117,19 @@ public final class Monitor {
if (cachedProxies.containsKey(analyzerType)) {
return (A) cachedProxies.get(analyzerType);
}
List<A> analyzers = getMonitor().getAnalyzers(analyzerType);
/*
* Next call is needed to check if analyzers are available (throws
* exception otherwise!)
*/
getMonitor().getAnalyzers(analyzerType);
cachedCheck.put(analyzerType, true);
if (analyzers.size() == 1) {
// Do not depend on proxy
return analyzers.iterator().next();
}
// create proxy
Class<?>[] proxyInterfaces = new Class[]{analyzerType};
Delegator<A> delegator = new Delegator<A>(analyzerType);
A proxy = (A) Proxy.newProxyInstance(analyzerType.getClassLoader(),
proxyInterfaces, new Delegator<A>(analyzers));
proxyInterfaces, delegator);
cachedProxies.put(analyzerType, proxy);
return proxy;
}
......@@ -166,15 +170,15 @@ public final class Monitor {
/**
* Register a new analyzer and invalidate caches.
*
* TODO we should also update old proxies to include the new analyzer, if it
* matches the interface.
*
* @param analyzer
*/
public static <A extends Analyzer> void registerAnalyzer(A analyzer) {
cachedCheck.clear();
cachedProxies.clear();
getMonitor().registerAnalyzer(analyzer);
for (Delegator<?> delegator : delegators) {
delegator.updateAnalyzers();
}
}
/**
......@@ -191,8 +195,26 @@ public final class Monitor {
private final List<A> analyzers;
public Delegator(List<A> analyzers) {
this.analyzers = analyzers;
public final Class<A> analyzerClass;
public Delegator(Class<A> analyzerClass) {
this.analyzerClass = analyzerClass;
this.analyzers = new LinkedList<>();
updateAnalyzers();
}
/**
* Update the proxy if a new analyzer is added.
*
* @param analyzers
*/
public void updateAnalyzers() {
this.analyzers.clear();
try {
this.analyzers.addAll(getMonitor().getAnalyzers(analyzerClass));
} catch (AnalyzerNotAvailableException e) {
throw new AssertionError("No analyzer available.");
}
}
@Override
......
......@@ -38,6 +38,14 @@ public interface NodeInformation {
/*
* General functions
*/
/**
* Only show active components.
*
* @return
*/
public boolean isActive();
/**
* This string is - for example - shown in the visualization. Add all the
* relevant information you want to appear there.
......
......@@ -21,26 +21,47 @@
package de.tudarmstadt.maki.simonstrator.api.component.pubsub.analyzer;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Analyzer;
import de.tudarmstadt.maki.simonstrator.api.component.pubsub.Notification;
/**
* A forwarding Analyzer
* A forwarding Analyzer (usually only useful in an Ad Hoc Scenario)
*
* @author bjoern
* @author Bjoern Richerzhagen
*
*/
public interface PubSubNotificationForwardingAnalyzer extends Analyzer {
/**
* Invoked when the given host (localhost) forwarded a notification.
*
* @param localhost
* @param notification
* @param receivedFrom
* (optional) the ID of the host that forwarded this notification
* to us.
* @param color
* allows distinction between different types of messages being
* forwarded.
* (optional) allows distinction between different types of
* messages being forwarded.
*/
public void onForwardNotification(Host localhost,
Notification notification, int color);
public void onForwardNotification(Host localhost, Notification notification,
INodeID receivedFrom, int color);
/**
* Invoked when the given host (localhost) decided to drop a notification
* instead of forwarding it further down the line.
*
* @param localhost
* @param notification
* @param receivedFrom
* (optional) the ID of the host that forwarded this notification
* to us.
* @param color
* (optional) allows distinction between different types of
* messages being dropped.
*/
public void onDropNotification(Host localhost, Notification notification,
INodeID receivedFrom, int color);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment