
org.sapia.ubik.rmi.replication.ReplicatedCommand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sapia_ubik Show documentation
Show all versions of sapia_ubik Show documentation
A RMI-like distributed computing framework
The newest version!
package org.sapia.ubik.rmi.replication;
import org.sapia.ubik.net.ServerAddress;
import org.sapia.ubik.rmi.server.Hub;
import org.sapia.ubik.rmi.server.invocation.InvokeCommand;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.rmi.RemoteException;
import java.util.HashSet;
import java.util.Set;
/**
* Wraps an InvokeCommand
that is intented to be replicated to the different
* servers in a domain or cluster.
*
* @see #getReplicationContext()
*
* @author Yanick Duchesne
*
* - Copyright:
- Copyright © 2002-2004 Sapia Open Source Software. All Rights Reserved.
* - License:
- Read the license.txt file of the jar or visit the
* license page at the Sapia OSS web site
*
*/
public abstract class ReplicatedCommand extends InvokeCommand {
private Set _visited = new HashSet();
private Set _targets;
private ReplicatedInvoker _invoker;
private boolean _executed;
private boolean _synchronous;
private boolean _disabled;
/** Do not call; used for externalization only. */
public ReplicatedCommand() {
}
/**
* @param cmd the InvokeCommand
to replicate.
* @param targets the Set
of ServerAddress
es that are
* targeted by the command. If null
, then all siblings will be targeted.
* @param invoker the ReplicatedInvoker
implementation in charge of
* performing replicated method invocations.
*/
public ReplicatedCommand(InvokeCommand cmd, Set targets,
ReplicatedInvoker invoker, boolean synchronous) {
super(cmd.getOID(), cmd.getMethodName(), cmd.getParams(),
cmd.getParameterTypes(), null);
_targets = targets;
_invoker = invoker;
_synchronous = synchronous;
}
/**
* This method's implementation internally calls the getReplicationContext()
* method. The returned ReplicationContext
is used as a hook to the server
* in which this command is executed. Internally, the method selects the next server
* to which this instance should be dispatched, and executes the command that this
* instance wraps.
*
* If the execution is successful, this instance is dispatched by means of the
* ReplicationContext
.
*
* @see #getReplicationContext()
*
* @see org.sapia.ubik.rmi.server.RMICommand#execute()
*/
public Object execute() throws Throwable {
if (_disabled) {
return super.execute();
}
Object toReturn;
Hub.serverRuntime.dispatchEvent(new ReplicationEvent(this));
Set siblings = _invoker.getSiblings();
ReplicationStrategy strat = new ReplicationStrategy(_visited, _targets,
siblings);
ServerAddress addr;
ServerAddress current = getServerAddress();
if (_executed) {
convertParams(_invoker.getClass().getClassLoader());
toReturn = _invoker.invoke(super.getMethodName(),
super.getParameterTypes(), super.getParams());
} else {
if (_targets != null) {
if (_targets.contains(current)) {
toReturn = super.execute();
_executed = true;
_targets.remove(current);
} else {
_executed = true;
toReturn = send(strat.selectNextSibling());
return toReturn;
}
} else {
toReturn = super.execute();
_executed = true;
}
if ((addr = strat.selectNextSibling()) != null) {
if (!_disabled) {
send(addr);
}
}
}
return toReturn;
}
/**
* @return the ReplicatedInvoker
that this instance holds.
*/
public ReplicatedInvoker getReplicatedInvoker() {
return _invoker;
}
/**
* Disables replication behavior (this command will execute as a normal
* InvokeCommand
).
*/
public void disable() {
_disabled = true;
}
/**
* @see org.sapia.ubik.rmi.server.invocation.InvokeCommand#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
super.readExternal(in);
_visited = (Set) in.readObject();
_targets = (Set) in.readObject();
_invoker = (ReplicatedInvoker) in.readObject();
_executed = in.readBoolean();
_synchronous = in.readBoolean();
_disabled = in.readBoolean();
}
/**
* @see org.sapia.ubik.rmi.server.invocation.InvokeCommand#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(_visited);
out.writeObject(_targets);
out.writeObject(_invoker);
out.writeBoolean(_executed);
out.writeBoolean(_synchronous);
out.writeBoolean(_disabled);
}
/**
* This method synchronously or asynchronously sends this instance to the server
* at the given address.
* @param next the ServerAddress
of the "next" server to which this
* instance should be sent.
* @return the result of the invocation.
* @throws RemoteException if a problem occurs sending this instance.
*/
protected Object send(ServerAddress next) throws RemoteException {
SendHelper helper = new SendHelper(this, next, _synchronous);
if (_synchronous) {
try {
return helper.send();
} catch (Throwable t) {
if (t instanceof RemoteException) {
throw (RemoteException) t;
}
throw new RemoteException("Exception caught replicating command", t);
}
} else {
try {
helper.send();
} catch (Throwable t) {
if (t instanceof RemoteException) {
throw (RemoteException) t;
}
throw new RemoteException("Exception caught replicating command", t);
}
return null;
}
}
protected Set getVisitedAddresses(){
return _visited;
}
protected Set getTargetAddresses(){
return _targets;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy