From d99d17ca7adc40447901686a1730b1b0ee647ae4 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Fri, 27 Aug 2010 01:06:06 +0000 Subject: [PATCH] Make NodeRequests a bit fancier for hitting multiple nodes. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6134 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/peer/server/PeerManager.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java index 89cb38cb6..ef0d80277 100644 --- a/src/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/java/com/threerings/presents/peer/server/PeerManager.java @@ -166,8 +166,21 @@ public abstract class PeerManager protected abstract void execute (); } + /** + * Encapsulates code that is meant to be executed one or more servers and return a result. + * + *

Note well: the request you provide is serialized and sent to the server to which + * the member is currently connection. This means you MUST NOT instantiate a NodeRequest + * anonymously because that will maintain an implicit non-transient reference to its containing + * class which will then also be serialized (assuming it is even serializable). + */ public static abstract class NodeRequest implements Streamable { + /** Returns true if this request should be executed on the specified node. This will be + * called on the originating server to decide whether or not to deliver the request to the + * server in question. */ + public abstract boolean isApplicable (NodeObject nodeobj); + /** Invokes the action on the target server. */ public void invoke (final InvocationService.ResultListener listener) { try { @@ -459,22 +472,33 @@ public abstract class PeerManager * this function will report success. */ public void invokeNodeRequest ( - final NodeRequest request, final InvocationService.ConfirmListener listener) + final NodeRequest request, final InvocationService.ConfirmListener listener, + final Runnable onDropped) { // if we're not on the dobjmgr thread, get there if (!_omgr.isDispatchThread()) { _omgr.postRunnable(new Runnable() { public void run () { - invokeNodeRequest(request, listener); + invokeNodeRequest(request, listener, onDropped); } }); return; } // build a set of node names (including the local node) to - final Set nodes = Sets.newHashSet(_nodeobj.nodeName); + final Set nodes = Sets.newHashSet(); + if (request.isApplicable(_nodeobj)) { + nodes.add(_nodeobj.nodeName); + } for (PeerNode peer : _peers.values()) { - nodes.add(peer.getNodeName()); + if (request.isApplicable(peer.nodeobj)) { + nodes.add(peer.getNodeName()); + } + } + + if (nodes.isEmpty() && onDropped != null) { + onDropped.run(); + return; } // serialize the action to make sure we can