Remove invocation receiver mappings from the receivers table when they are
unregistered. Flush invocation listener mappings after an expiry period if they were not already removed by virtue of receiving a response. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2040 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: InvocationDirector.java,v 1.23 2002/10/27 22:24:20 mdb Exp $
|
// $Id: InvocationDirector.java,v 1.24 2002/12/08 02:18:50 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.client;
|
package com.threerings.presents.client;
|
||||||
|
|
||||||
@@ -126,6 +126,14 @@ public class InvocationDirector
|
|||||||
|
|
||||||
// if we're logged on, clear out any receiver id mapping
|
// if we're logged on, clear out any receiver id mapping
|
||||||
if (_clobj != null) {
|
if (_clobj != null) {
|
||||||
|
Registration rreg = (Registration)
|
||||||
|
_clobj.receivers.get(receiverCode);
|
||||||
|
if (rreg == null) {
|
||||||
|
Log.warning("Receiver unregistered for which we have no " +
|
||||||
|
"id to code mapping [code=" + receiverCode + "].");
|
||||||
|
} else {
|
||||||
|
_receivers.remove(rreg.receiverId);
|
||||||
|
}
|
||||||
_clobj.removeFromReceivers(receiverCode);
|
_clobj.removeFromReceivers(receiverCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,6 +185,7 @@ public class InvocationDirector
|
|||||||
ListenerMarshaller lm = (ListenerMarshaller)arg;
|
ListenerMarshaller lm = (ListenerMarshaller)arg;
|
||||||
lm.callerOid = _clobj.getOid();
|
lm.callerOid = _clobj.getOid();
|
||||||
lm.requestId = nextRequestId();
|
lm.requestId = nextRequestId();
|
||||||
|
lm.mapStamp = System.currentTimeMillis();
|
||||||
// create a mapping for this marshaller so that we can
|
// create a mapping for this marshaller so that we can
|
||||||
// properly dispatch responses sent to it
|
// properly dispatch responses sent to it
|
||||||
_listeners.put(lm.requestId, lm);
|
_listeners.put(lm.requestId, lm);
|
||||||
@@ -237,7 +246,10 @@ public class InvocationDirector
|
|||||||
Log.warning("Received invocation response for which we have " +
|
Log.warning("Received invocation response for which we have " +
|
||||||
"no registered listener [reqId=" + reqId +
|
"no registered listener [reqId=" + reqId +
|
||||||
", methId=" + methodId +
|
", methId=" + methodId +
|
||||||
", args=" + StringUtil.toString(args) + "].");
|
", args=" + StringUtil.toString(args) + "]. " +
|
||||||
|
"It is possble that this listener was flushed " +
|
||||||
|
"because the response did not arrive within " +
|
||||||
|
LISTENER_MAX_AGE + " milliseconds.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,6 +266,13 @@ public class InvocationDirector
|
|||||||
", args=" + StringUtil.toString(args) + "].");
|
", args=" + StringUtil.toString(args) + "].");
|
||||||
Log.logStackTrace(t);
|
Log.logStackTrace(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// flush expired listeners periodically
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if (now - _lastFlushTime > LISTENER_FLUSH_INTERVAL) {
|
||||||
|
_lastFlushTime = now;
|
||||||
|
flushListeners(now);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -331,7 +350,33 @@ public class InvocationDirector
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Flushes listener mappings that are older than {@link
|
||||||
|
* #LISTENER_MAX_AGE} milliseconds. An alternative to flushing
|
||||||
|
* listeners that did not explicitly receive a response within our
|
||||||
|
* expiry time period is to have the server's proxy listener send a
|
||||||
|
* message to the client when it is finalized. We then know that no
|
||||||
|
* server entity will subsequently use that proxy listener to send a
|
||||||
|
* response to the client. This involves more network traffic and
|
||||||
|
* complexity than seems necessary and if a user of the system does
|
||||||
|
* respond after their listener has been flushed, an informative
|
||||||
|
* warning will be logged. (Famous last words.)
|
||||||
|
*/
|
||||||
|
protected void flushListeners (long now)
|
||||||
|
{
|
||||||
|
if (_listeners.size() > 0) {
|
||||||
|
Iterator iter = _listeners.values().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
ListenerMarshaller lm = (ListenerMarshaller)iter.next();
|
||||||
|
if (now - lm.mapStamp > LISTENER_MAX_AGE) {
|
||||||
|
Log.debug("Flushing marshaller " + lm + ".");
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Used to generate monotonically increasing invocation request ids.
|
* Used to generate monotonically increasing invocation request ids.
|
||||||
*/
|
*/
|
||||||
protected synchronized short nextRequestId ()
|
protected synchronized short nextRequestId ()
|
||||||
@@ -373,4 +418,13 @@ public class InvocationDirector
|
|||||||
/** All registered receivers are maintained in a list so that we can
|
/** All registered receivers are maintained in a list so that we can
|
||||||
* assign receiver ids to them when we go online. */
|
* assign receiver ids to them when we go online. */
|
||||||
protected ArrayList _reclist = new ArrayList();
|
protected ArrayList _reclist = new ArrayList();
|
||||||
|
|
||||||
|
/** The last time we flushed our listeners. */
|
||||||
|
protected long _lastFlushTime;
|
||||||
|
|
||||||
|
/** The minimum interval between listener flush attempts. */
|
||||||
|
protected static final long LISTENER_FLUSH_INTERVAL = 15000L;
|
||||||
|
|
||||||
|
/** Listener mappings older than 90 seconds are reaped. */
|
||||||
|
protected static final long LISTENER_MAX_AGE = 90 * 1000L;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: InvocationMarshaller.java,v 1.2 2002/09/20 04:52:49 mdb Exp $
|
// $Id: InvocationMarshaller.java,v 1.3 2002/12/08 02:18:50 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.data;
|
package com.threerings.presents.data;
|
||||||
|
|
||||||
@@ -46,6 +46,10 @@ public class InvocationMarshaller
|
|||||||
* marshalling listener. This is only valid on the client. */
|
* marshalling listener. This is only valid on the client. */
|
||||||
public transient InvocationListener listener;
|
public transient InvocationListener listener;
|
||||||
|
|
||||||
|
/** The time at which this listener marshaller was registered.
|
||||||
|
* This is only valid on the client. */
|
||||||
|
public transient long mapStamp;
|
||||||
|
|
||||||
/** The distributed object manager to use when dispatching proxied
|
/** The distributed object manager to use when dispatching proxied
|
||||||
* responses. This is only valid on the server. */
|
* responses. This is only valid on the server. */
|
||||||
public transient DObjectManager omgr;
|
public transient DObjectManager omgr;
|
||||||
|
|||||||
Reference in New Issue
Block a user