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;
|
||||
|
||||
@@ -126,6 +126,14 @@ public class InvocationDirector
|
||||
|
||||
// if we're logged on, clear out any receiver id mapping
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -177,6 +185,7 @@ public class InvocationDirector
|
||||
ListenerMarshaller lm = (ListenerMarshaller)arg;
|
||||
lm.callerOid = _clobj.getOid();
|
||||
lm.requestId = nextRequestId();
|
||||
lm.mapStamp = System.currentTimeMillis();
|
||||
// create a mapping for this marshaller so that we can
|
||||
// properly dispatch responses sent to it
|
||||
_listeners.put(lm.requestId, lm);
|
||||
@@ -237,7 +246,10 @@ public class InvocationDirector
|
||||
Log.warning("Received invocation response for which we have " +
|
||||
"no registered listener [reqId=" + reqId +
|
||||
", 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;
|
||||
}
|
||||
|
||||
@@ -254,6 +266,13 @@ public class InvocationDirector
|
||||
", args=" + StringUtil.toString(args) + "].");
|
||||
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.
|
||||
*/
|
||||
protected synchronized short nextRequestId ()
|
||||
@@ -373,4 +418,13 @@ public class InvocationDirector
|
||||
/** All registered receivers are maintained in a list so that we can
|
||||
* assign receiver ids to them when we go online. */
|
||||
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;
|
||||
|
||||
@@ -46,6 +46,10 @@ public class InvocationMarshaller
|
||||
* marshalling listener. This is only valid on the client. */
|
||||
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
|
||||
* responses. This is only valid on the server. */
|
||||
public transient DObjectManager omgr;
|
||||
|
||||
Reference in New Issue
Block a user