From c365afa2fc4691671bfff9652179fabd7ac3ecd7 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 13 Jun 2007 22:37:53 +0000 Subject: [PATCH] Rejiggered the way things are handled when using a Client to proxy events from another server. The PeerManager needs both to rewrite the oid of the events before dispatching them and to assign an eventId to them so that they will not be filtered by PresentsClient when deciding whether or not to send them along to its client. Also fixed compound event dispatch in the process. Now proxy subscribers will be notified once of a compound event rather than of each individual internal event. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4729 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/presents/client/Client.java | 11 +++++ .../presents/client/ClientDObjectMgr.java | 42 ++++++++++--------- .../presents/peer/server/PeerManager.java | 14 ++++++- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/java/com/threerings/presents/client/Client.java b/src/java/com/threerings/presents/client/Client.java index 9fb8dd5b1..c9bd7ba62 100644 --- a/src/java/com/threerings/presents/client/Client.java +++ b/src/java/com/threerings/presents/client/Client.java @@ -31,6 +31,8 @@ import com.samskivert.util.RunQueue; import com.threerings.presents.Log; import com.threerings.presents.data.ClientObject; import com.threerings.presents.data.InvocationCodes; +import com.threerings.presents.dobj.DEvent; +import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObjectManager; import com.threerings.presents.net.AuthResponseData; import com.threerings.presents.net.BootstrapData; @@ -483,6 +485,15 @@ public class Client // before turning the client loose to do things like request invocation services } + /** + * If this client is being used to proxy events from another server, this method can be + * overridden to adjust the event in any way needed prior to dispatching the event. + */ + protected void adjustForProxy (DObject target, DEvent event) + { + // nothing by default + } + /** * Called every five seconds; ensures that we ping the server if we haven't communicated in a * long while and periodically resyncs the client and server clock deltas. diff --git a/src/java/com/threerings/presents/client/ClientDObjectMgr.java b/src/java/com/threerings/presents/client/ClientDObjectMgr.java index 90ab95266..dc54b0e8b 100644 --- a/src/java/com/threerings/presents/client/ClientDObjectMgr.java +++ b/src/java/com/threerings/presents/client/ClientDObjectMgr.java @@ -159,7 +159,7 @@ public class ClientDObjectMgr } else if (obj instanceof EventNotification) { DEvent evt = ((EventNotification)obj).getEvent(); // Log.info("Dispatch event: " + evt); - dispatchEvent(evt); + dispatchEvent(evt, true); } else if (obj instanceof ObjectResponse) { registerObjectAndNotify((ObjectResponse)obj); @@ -201,18 +201,8 @@ public class ClientDObjectMgr * Called when a new event arrives from the server that should be dispatched to subscribers * here on the client. */ - protected void dispatchEvent (DEvent event) + protected void dispatchEvent (DEvent event, boolean notifyProxies) { - // if this is a compound event, we need to process its contained events in order - if (event instanceof CompoundEvent) { - List events = ((CompoundEvent)event).getEvents(); - int ecount = events.size(); - for (int i = 0; i < ecount; i++) { - dispatchEvent(events.get(i)); - } - return; - } - // look up the object on which we're dispatching this event int toid = event.getTargetOid(); DObject target = _ocache.get(toid); @@ -223,18 +213,32 @@ public class ClientDObjectMgr return; } - // because we might be acting as a proxy between servers, we rewrite the event's target oid - // using the oid currently configured on the distributed object (we will have it mapped in - // our remote server's oid space, but it may have been remapped into the oid space of the - // local server) - event.setTargetOid(target.getOid()); + // because we might be acting as a proxy between servers, we may need to fiddle with this + // event before we dispatch it + _client.adjustForProxy(target, event); + + // if this is a compound event, we need to process its contained events in order + if (event instanceof CompoundEvent) { + // notify our proxy subscribers in one fell swoop + target.notifyProxies(event); + + // now break the event up and dispatch each event individually + List events = ((CompoundEvent)event).getEvents(); + int ecount = events.size(); + for (int i = 0; i < ecount; i++) { + dispatchEvent(events.get(i), false); + } + return; + } try { // apply the event to the object boolean notify = event.applyToObject(target); - // forward to any proxies - target.notifyProxies(event); + // forward to any proxies (or not if we're dispatching part of a compound event) + if (notifyProxies) { + target.notifyProxies(event); + } // if this is an object destroyed event, we need to remove the object from our table if (event instanceof ObjectDestroyedEvent) { diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java index f57d91d3d..4537f326b 100644 --- a/src/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/java/com/threerings/presents/peer/server/PeerManager.java @@ -47,6 +47,7 @@ import com.threerings.presents.client.ClientObserver; import com.threerings.presents.data.ClientObject; import com.threerings.presents.dobj.AttributeChangeListener; import com.threerings.presents.dobj.AttributeChangedEvent; +import com.threerings.presents.dobj.DEvent; import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.EntryAddedEvent; import com.threerings.presents.dobj.EntryRemovedEvent; @@ -702,7 +703,18 @@ public class PeerManager public PeerNode (NodeRecord record) { _record = record; - _client = new Client(null, PresentsServer.omgr); + _client = new Client(null, PresentsServer.omgr) { + protected void adjustForProxy (DObject target, DEvent event) { + super.adjustForProxy(target, event); + // rewrite the event's target oid using the oid currently configured on the + // distributed object (we will have it mapped in our remote server's oid space, + // but it may have been remapped into the oid space of the local server) + event.setTargetOid(target.getOid()); + // assign an eventId to this event so that our stale event detection code can + // properly deal with it + event.eventId = PresentsServer.omgr.getNextEventId(true); + } + }; _client.addClientObserver(this); }