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
This commit is contained in:
@@ -166,8 +166,21 @@ public abstract class PeerManager
|
|||||||
protected abstract void execute ();
|
protected abstract void execute ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates code that is meant to be executed one or more servers and return a result.
|
||||||
|
*
|
||||||
|
* <p><b>Note well</b>: 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
|
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. */
|
/** Invokes the action on the target server. */
|
||||||
public void invoke (final InvocationService.ResultListener listener) {
|
public void invoke (final InvocationService.ResultListener listener) {
|
||||||
try {
|
try {
|
||||||
@@ -459,22 +472,33 @@ public abstract class PeerManager
|
|||||||
* this function will report success.
|
* this function will report success.
|
||||||
*/
|
*/
|
||||||
public void invokeNodeRequest (
|
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 we're not on the dobjmgr thread, get there
|
||||||
if (!_omgr.isDispatchThread()) {
|
if (!_omgr.isDispatchThread()) {
|
||||||
_omgr.postRunnable(new Runnable() {
|
_omgr.postRunnable(new Runnable() {
|
||||||
public void run () {
|
public void run () {
|
||||||
invokeNodeRequest(request, listener);
|
invokeNodeRequest(request, listener, onDropped);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// build a set of node names (including the local node) to
|
// build a set of node names (including the local node) to
|
||||||
final Set<String> nodes = Sets.newHashSet(_nodeobj.nodeName);
|
final Set<String> nodes = Sets.newHashSet();
|
||||||
|
if (request.isApplicable(_nodeobj)) {
|
||||||
|
nodes.add(_nodeobj.nodeName);
|
||||||
|
}
|
||||||
for (PeerNode peer : _peers.values()) {
|
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
|
// serialize the action to make sure we can
|
||||||
|
|||||||
Reference in New Issue
Block a user