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
This commit is contained in:
Michael Bayne
2007-02-03 01:14:17 +00:00
parent 3d125f64a8
commit e1c5d01afd
2 changed files with 70 additions and 6 deletions
@@ -223,6 +223,12 @@ public class ClientDObjectMgr
return; 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 { try {
// apply the event to the object // apply the event to the object
boolean notify = event.applyToObject(target); boolean notify = event.applyToObject(target);
@@ -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 // from interface DObjectManager
public boolean isManager (DObject object) public boolean isManager (DObject object)
{ {
@@ -112,8 +128,7 @@ public class PresentsDObjectMgr
} }
// from interface DObjectManager // from interface DObjectManager
public <T extends DObject> void subscribeToObject ( public <T extends DObject> void subscribeToObject (int oid, Subscriber<T> target)
int oid, Subscriber<T> target)
{ {
if (oid <= 0) { if (oid <= 0) {
target.requestFailed(oid, new ObjectAccessException("Invalid oid " + oid + ".")); target.requestFailed(oid, new ObjectAccessException("Invalid oid " + oid + "."));
@@ -124,8 +139,7 @@ public class PresentsDObjectMgr
} }
// from interface DObjectManager // from interface DObjectManager
public <T extends DObject> void unsubscribeFromObject ( public <T extends DObject> void unsubscribeFromObject (int oid, Subscriber<T> target)
int oid, Subscriber<T> target)
{ {
// queue up an access object event // queue up an access object event
postEvent(new AccessObjectEvent<T>(oid, target, AccessObjectEvent.UNSUBSCRIBE)); postEvent(new AccessObjectEvent<T>(oid, target, AccessObjectEvent.UNSUBSCRIBE));
@@ -257,10 +271,38 @@ public class PresentsDObjectMgr
((Runnable)unit).run(); ((Runnable)unit).run();
} else if (unit instanceof CompoundEvent) { } 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<DEvent> 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 { } 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) { } catch (VirtualMachineError e) {
@@ -861,6 +903,19 @@ public class PresentsDObjectMgr
protected Histogram _histo = new Histogram(0, 20000, 10); 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. */ /** A flag indicating that the event dispatcher is still running. */
protected boolean _running = true; protected boolean _running = true;
@@ -886,6 +941,9 @@ public class PresentsDObjectMgr
/** The default access controller to use when creating distributed objects. */ /** The default access controller to use when creating distributed objects. */
protected AccessController _defaultController; protected AccessController _defaultController;
/** Maintains proxy information for any proxied distributed objects. */
protected HashIntMap<ProxyReference> _proxies = new HashIntMap<ProxyReference>();
/** We keep track of which thread is executing the event loop so that other services can /** 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 * enforce restrictions on code that should or should not be called from the event dispatch
* thread. */ * thread. */