use of org.teiid.query.ReplicatedObject in project teiid by teiid.
the class JGroupsObjectReplicator method replicate.
@Override
public <T, S> T replicate(String mux_id, Class<T> iface, final S object, long startTimeout) throws Exception {
Channel channel = channelFactory.createChannel(mux_id);
// To keep the order of methods same at all the nodes.
TreeMap<String, Method> methods = new TreeMap<String, Method>();
for (Method method : iface.getMethods()) {
if (method.getAnnotation(Replicated.class) == null) {
continue;
}
methods.put(method.toGenericString(), method);
}
final HashMap<Method, Short> methodMap = new HashMap<Method, Short>();
final ArrayList<Method> methodList = new ArrayList<Method>();
for (String method : methods.keySet()) {
methodList.add(methods.get(method));
methodMap.put(methods.get(method), (short) (methodList.size() - 1));
}
Method hasState = ReplicatedObject.class.getMethod(HAS_STATE, new Class<?>[] { Serializable.class });
methodList.add(hasState);
methodMap.put(hasState, (short) (methodList.size() - 1));
Method sendState = JGroupsObjectReplicator.Streaming.class.getMethod(SEND_STATE, new Class<?>[] { Serializable.class, Address.class });
methodList.add(sendState);
methodMap.put(sendState, (short) (methodList.size() - 1));
// add in streaming methods
Method createState = JGroupsObjectReplicator.Streaming.class.getMethod(CREATE_STATE, new Class<?>[] { Serializable.class });
methodList.add(createState);
methodMap.put(createState, (short) (methodList.size() - 1));
Method buildState = JGroupsObjectReplicator.Streaming.class.getMethod(BUILD_STATE, new Class<?>[] { Serializable.class, byte[].class });
methodList.add(buildState);
methodMap.put(buildState, (short) (methodList.size() - 1));
Method finishState = JGroupsObjectReplicator.Streaming.class.getMethod(FINISH_STATE, new Class<?>[] { Serializable.class });
methodList.add(finishState);
methodMap.put(finishState, (short) (methodList.size() - 1));
ReplicatedInvocationHandler<S> proxy = new ReplicatedInvocationHandler<S>(object, methodMap);
/*
* TODO: could have an object implement streaming
* Override the normal handle method to support streaming
*/
ReplicatorRpcDispatcher disp = new ReplicatorRpcDispatcher<S>(channel, proxy, proxy, object, object, methodMap, methodList);
proxy.setDisp(disp);
disp.setMethodLookup(new MethodLookup() {
public Method findMethod(short id) {
return methodList.get(id);
}
});
T replicatedProxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] { iface }, proxy);
boolean success = false;
try {
channel.connect(mux_id);
if (object instanceof ReplicatedObject) {
((ReplicatedObject) object).setAddress(channel.getAddress());
proxy.pullState(null, null, null, startTimeout, startTimeout != 0 ? STATE_TIMEOUT : 0);
}
success = true;
return replicatedProxy;
} catch (Throwable e) {
if (e instanceof Exception) {
throw (Exception) e;
}
throw new TeiidRuntimeException(RuntimePlugin.Event.TEIID40104, e);
} finally {
if (!success) {
channel.close();
} else {
synchronized (disp) {
// mark as initialized so that state can be pulled if needed
disp.initialized = true;
}
}
}
}
Aggregations