A new type of general communication between peers - the NodeRequest - it's a lot like a NodeAction but produces a result which is sent back via the ResultListener.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6070 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Mike Thomas
2010-06-01 23:48:50 +00:00
parent 3c2c86da60
commit 7101012413
5 changed files with 98 additions and 1 deletions
@@ -65,6 +65,7 @@ import com.threerings.presents.dobj.Subscriber;
import com.threerings.presents.annotation.MainInvoker;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.InvocationService;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.ClientManager;
import com.threerings.presents.server.InvocationException;
@@ -164,6 +165,20 @@ public abstract class PeerManager
protected abstract void execute ();
}
public static abstract class NodeRequest implements Streamable
{
/** Invokes the action on the target server. */
public void invoke (final InvocationService.ResultListener listener) {
try {
execute(listener);
} catch (Throwable t) {
log.warning(getClass().getName() + " failed.", t);
}
}
protected abstract void execute (InvocationService.ResultListener listener);
}
/** Returned by {@link #getStats}. */
public static class Stats implements Cloneable
{
@@ -420,6 +435,21 @@ public abstract class PeerManager
}
}
/**
* Invokes a node request on a specific node and returns the result through the listener.
*/
public void invokeNodeRequest (String nodeName, NodeRequest request,
InvocationService.ResultListener listener)
{
PeerNode peer = _peers.get(nodeName);
if (peer != null) {
peer.nodeobj.peerService.invokeRequest(
peer.getClient(), flattenRequest(request), listener);
} else if (nodeName.equals(_nodeName)) {
invokeRequest(null, flattenRequest(request), listener);
}
}
/**
* Initiates a proxy on an object that is managed by the specified peer. The object will be
* proxied into this server's distributed object space and its local oid reported back to the
@@ -822,6 +852,26 @@ public abstract class PeerManager
}
}
// from interface PeerProvider
public void invokeRequest (ClientObject caller, byte[] serializedAction,
InvocationService.ResultListener listener)
{
NodeRequest request = null;
try {
ObjectInputStream oin =
new ObjectInputStream(new ByteArrayInputStream(serializedAction));
request = (NodeRequest)oin.readObject();
_injector.injectMembers(request);
request.invoke(listener);
} catch (Exception e) {
log.warning("Failed to execute node request",
"from", (caller == null) ? "self" : caller.who(),
"request", request, "serializedSize", serializedAction.length, e);
listener.requestFailed("Failed to execute node request");
}
}
// from interface PeerProvider
public void generateReport (ClientObject caller, String type,
PeerService.ResultListener listener)
@@ -1142,6 +1192,22 @@ public abstract class PeerManager
}
}
/**
* Flattens the supplied node request into bytes.
*/
protected byte[] flattenRequest (NodeRequest request)
{
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(request);
return bout.toByteArray();
} catch (Exception e) {
throw new IllegalArgumentException(
"Failed to serialize node request [request=" + request + "].", e);
}
}
protected void lockAcquired (NodeObject.Lock lock, long wait, ResultListener<String> listener)
{
_nodeobj.addToLocks(lock);