HARMIClientpublic class HARMIClient extends Object implements InvocationHandler, HARMIProxy, Serializable
Fields Summary |
---|
private static final long | serialVersionUIDThe serialVersionUID | private static final Logger | log | protected static final Method | TO_STRING{@link Object#toString} method reference. | protected static final Method | HASH_CODE{@link Object#hashCode} method reference. | protected static final Method | EQUALS{@link Object#equals} method reference. | protected String | key | protected LoadBalancePolicy | loadBalancePolicy | protected transient Object | local | protected transient boolean | trace | FamilyClusterInfo | familyClusterInfo |
Constructors Summary |
---|
public HARMIClient()
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
| public HARMIClient(ArrayList targets, LoadBalancePolicy policy, String key)
this(targets, 0, policy, key, null);
| public HARMIClient(ArrayList targets, long initViewId, LoadBalancePolicy policy, String key, Object local)
this.familyClusterInfo = ClusteringTargetsRepository.initTarget (key, targets, initViewId);
//this.targets = targets;
this.loadBalancePolicy = policy;
this.loadBalancePolicy.init(this);
this.key = key;
this.local = local;
this.trace = log.isTraceEnabled();
if( trace )
log.trace("Init, cluterInfo: "+familyClusterInfo+", policy="+loadBalancePolicy);
|
Methods Summary |
---|
public java.lang.reflect.Method | findLocalMethod(java.lang.reflect.Method method, java.lang.Object[] args)
return method;
| public java.lang.Object | getRemoteTarget()
// System.out.println("number of targets: " + targets.size());
return loadBalancePolicy.chooseTarget(this.familyClusterInfo, null); // legacy, no Invocation object in raw HA-RMI
| public java.lang.Object | invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
// The isLocal call is handled by the proxy
String name = method.getName();
if (method.equals(TO_STRING))
{
StringBuffer tmp = new StringBuffer(super.toString());
tmp.append('(");
tmp.append(familyClusterInfo);
tmp.append(')");
return tmp.toString();
}
else if (name.equals("equals"))
{
return method.invoke(this, args);
}
else if (name.equals("hashCode"))
{
return method.invoke(this, args);
}
else if (name.equals("isLocal") && (args == null || args.length == 0))
{
return method.invoke(this, args);
}
// we try to optimize the call locally first
//
if (local != null)
{
try
{
Method localMethod = findLocalMethod(method, args);
return localMethod.invoke(local, args);
}
catch (java.lang.reflect.InvocationTargetException ite)
{
throw ite.getTargetException();
}
}
else
{
return invokeRemote(null, method, args);
}
| public java.lang.Object | invokeRemote(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
boolean trace = log.isTraceEnabled();
HARMIServer target = (HARMIServer)getRemoteTarget();
while (target != null)
{
Exception lastException = null;
try
{
if( trace )
log.trace("Invoking on target="+target);
MarshalledInvocation mi = new MarshalledInvocation(null, method, args, null, null, null);
mi.setObjectName (""); //FIXME: Fake value! Bill's optimisations regarding MI make the hypothesis
// that ObjectName is always here otherwise the writeExternal code of MI
// "out.writeInt(payload.size() - 3);" is wrong
HARMIResponse rsp = target.invoke(this.familyClusterInfo.getCurrentViewId (), mi);
if (rsp.newReplicants != null)
{
if( trace )
{
log.trace("newReplicants: "+rsp.newReplicants);
}
updateClusterInfo (rsp.newReplicants, rsp.currentViewId);
//setTargets(rsp.newReplicants);
//currentViewId = rsp.currentViewId;
}
return rsp.response;
}
catch (java.rmi.ConnectException e)
{
lastException = e;
}
catch (java.rmi.ConnectIOException e)
{
lastException = e;
}
catch (java.rmi.NoSuchObjectException e)
{
lastException = e;
}
catch (java.rmi.UnmarshalException e)
{
lastException = e;
}
catch (java.rmi.UnknownHostException e)
{
lastException = e;
}
if( trace )
log.trace("Invoke failed, target="+target, lastException);
// If we reach here, this means that we must fail-over
remoteTargetHasFailed(target);
target = (HARMIServer)getRemoteTarget();
}
// if we get here this means list was exhausted
throw new java.rmi.RemoteException("Service unavailable.");
| public boolean | isLocal()
return local != null;
| private void | readObject(java.io.ObjectInputStream stream)
this.key = stream.readUTF();
ArrayList targets = (ArrayList)stream.readObject();
long vid = stream.readLong ();
this.loadBalancePolicy = (LoadBalancePolicy)stream.readObject();
HARMIServer server = (HARMIServer)HARMIServer.rmiServers.get(key);
// keep a reference on our family object
//
this.familyClusterInfo = ClusteringTargetsRepository.initTarget (this.key, targets, vid);
this.loadBalancePolicy.init(this);
if (server != null)
{
synchronized (targets)
{
try
{
targets = (ArrayList)server.getReplicants();
local = server.getLocal();
}
catch (Exception ignored)
{}
}
}
this.trace = log.isTraceEnabled();
if( trace )
log.trace("Init, clusterInfo: "+familyClusterInfo+", policy="+loadBalancePolicy);
| public void | remoteTargetHasFailed(java.lang.Object target)
removeDeadTarget(target);
| protected void | removeDeadTarget(java.lang.Object target)
//System.out.println("Size before : " + Integer.toString(targets.length));
if (this.familyClusterInfo != null)
this.familyClusterInfo.removeDeadTarget (target);
| public void | updateClusterInfo(java.util.ArrayList targets, long viewId)
if (familyClusterInfo != null)
this.familyClusterInfo.updateClusterInfo (targets, viewId);
| private void | writeObject(java.io.ObjectOutputStream stream)
// JBAS-2071 - sync on FCI to ensure targets and vid are consistent
ArrayList currentTargets = null;
long vid = 0;
synchronized (this.familyClusterInfo)
{
currentTargets = this.familyClusterInfo.getTargets();
vid = this.familyClusterInfo.getCurrentViewId ();
}
stream.writeUTF(key);
stream.writeObject(currentTargets);
stream.writeLong(vid);
stream.writeObject(loadBalancePolicy);
|
|