From e1c5d01afd66bbb8a77430e28862f1841ee126d1 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Sat, 3 Feb 2007 01:14:17 +0000 Subject: [PATCH] Added proxied object support to the distributed object manager framework. This exposes the need to write a Client that is optimized to act as a proxy instead of just using the one that is designed to run on a user's machine. However, this will be fine for now. Integration with PeerManager forthcoming. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4530 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/client/ClientDObjectMgr.java | 6 ++ .../presents/server/PresentsDObjectMgr.java | 70 +++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/java/com/threerings/presents/client/ClientDObjectMgr.java b/src/java/com/threerings/presents/client/ClientDObjectMgr.java index 9b6cd7353..cbf879308 100644 --- a/src/java/com/threerings/presents/client/ClientDObjectMgr.java +++ b/src/java/com/threerings/presents/client/ClientDObjectMgr.java @@ -223,6 +223,12 @@ 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()); + try { // apply the event to the object boolean notify = event.applyToObject(target); diff --git a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java index 831fffe66..2d0c32cc9 100644 --- a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java +++ b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java @@ -104,6 +104,22 @@ public class PresentsDObjectMgr } } + /** + * Registers an object managed by another distributed object manager (probably on another + * server). The local server will assign the object a proxy oid, and any events that come in on + * this object will be rewritten from their proxy oid to their original id before forwarding on + * to the originating object manager. + */ + public void registerProxyObject (DObject object, DObjectManager omgr) + { + int origObjectId = object.getOid(); + // register the object locally which will reassign its oid and set us as its manager + registerObject(object); + // and note a proxy reference for the object which we'll use to forward events back to its + // originating manager after converting them back to the original oid + _proxies.put(origObjectId, new ProxyReference(object.getOid(), omgr)); + } + // from interface DObjectManager public boolean isManager (DObject object) { @@ -112,8 +128,7 @@ public class PresentsDObjectMgr } // from interface DObjectManager - public void subscribeToObject ( - int oid, Subscriber target) + public void subscribeToObject (int oid, Subscriber target) { if (oid <= 0) { target.requestFailed(oid, new ObjectAccessException("Invalid oid " + oid + ".")); @@ -124,8 +139,7 @@ public class PresentsDObjectMgr } // from interface DObjectManager - public void unsubscribeFromObject ( - int oid, Subscriber target) + public void unsubscribeFromObject (int oid, Subscriber target) { // queue up an access object event postEvent(new AccessObjectEvent(oid, target, AccessObjectEvent.UNSUBSCRIBE)); @@ -257,10 +271,38 @@ public class PresentsDObjectMgr ((Runnable)unit).run(); } else if (unit instanceof CompoundEvent) { - processCompoundEvent((CompoundEvent)unit); + CompoundEvent event = (CompoundEvent)unit; + + // if this event is on a proxied object, forward it to the owning manager + ProxyReference proxy = _proxies.get(event.getTargetOid()); + if (proxy != null) { + // rewrite the oid into the originating manager's id space + event.setTargetOid(proxy.origObjectId); + List events = event.getEvents(); + for (int ii = 0, ll = events.size(); ii < ll; ii++) { + events.get(ii).setTargetOid(proxy.origObjectId); + } + // then pass it on to the originating manager to handle + proxy.origManager.postEvent(event); + + } else { + processCompoundEvent(event); + } } else { - processEvent((DEvent)unit); + DEvent event = (DEvent)unit; + + // if this event is on a proxied object, forward it to the owning manager + ProxyReference proxy = _proxies.get(event.getTargetOid()); + if (proxy != null) { + // rewrite the oid into the originating manager's id space + event.setTargetOid(proxy.origObjectId); + // then pass it on to the originating manager to handle + proxy.origManager.postEvent(event); + + } else { + processEvent(event); + } } } catch (VirtualMachineError e) { @@ -861,6 +903,19 @@ public class PresentsDObjectMgr protected Histogram _histo = new Histogram(0, 20000, 10); } + /** Tracks necessary information on a proxy distributed object. */ + protected static class ProxyReference + { + public int origObjectId; + public DObjectManager origManager; + + public ProxyReference (int origObjectId, DObjectManager origManager) + { + this.origObjectId = origObjectId; + this.origManager = origManager; + } + } + /** A flag indicating that the event dispatcher is still running. */ protected boolean _running = true; @@ -886,6 +941,9 @@ public class PresentsDObjectMgr /** The default access controller to use when creating distributed objects. */ protected AccessController _defaultController; + /** Maintains proxy information for any proxied distributed objects. */ + protected HashIntMap _proxies = new HashIntMap(); + /** We keep track of which thread is executing the event loop so that other services can * enforce restrictions on code that should or should not be called from the event dispatch * thread. */