Passing in the timestamp that dictates idleness allows us to propagate the idle

duration a bit less far. And Ray will be pleased to know that we're doing much
less redundant arithmetic.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6385 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2010-12-16 02:18:53 +00:00
parent 6a45fec4ea
commit 74c2c77443
7 changed files with 31 additions and 37 deletions
@@ -45,14 +45,12 @@ public abstract class Connection implements NetEventHandler
* @param channel The socket channel from which we'll be reading messages. * @param channel The socket channel from which we'll be reading messages.
* @param createStamp The time at which this connection was created. * @param createStamp The time at which this connection was created.
*/ */
public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp, public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp)
long idleTime)
throws IOException throws IOException
{ {
_cmgr = cmgr; _cmgr = cmgr;
_channel = channel; _channel = channel;
_lastEvent = createStamp; _lastEvent = createStamp;
_idleTime = idleTime;
_connectionId = ++_lastConnectionId; _connectionId = ++_lastConnectionId;
} }
@@ -147,15 +145,14 @@ public abstract class Connection implements NetEventHandler
} }
// from interface NetEventHandler // from interface NetEventHandler
public boolean checkIdle (long now) public boolean checkIdle (long idleStamp)
{ {
long idleMillis = now - _lastEvent; if (_lastEvent > idleStamp) {
if (idleMillis < _idleTime) {
return false; return false;
} }
if (!isClosed()) { if (!isClosed()) {
log.info("Disconnecting non-communicative client", log.info("Disconnecting non-communicative client",
"conn", this, "idle", idleMillis + "ms"); "conn", this, "idle", (idleStamp - _lastEvent) + "ms");
} }
return true; return true;
} }
@@ -200,8 +197,6 @@ public abstract class Connection implements NetEventHandler
protected int _connectionId; protected int _connectionId;
protected long _idleTime;
/** The last connection id assigned. */ /** The last connection id assigned. */
protected static int _lastConnectionId; protected static int _lastConnectionId;
} }
@@ -171,8 +171,9 @@ public abstract class ConnectionManager extends LoopingThread
} }
// close connections that have had no network traffic for too long // close connections that have had no network traffic for too long
long idleStamp = iterStamp - _idleTime;
for (NetEventHandler handler : _handlers.values()) { for (NetEventHandler handler : _handlers.values()) {
if (handler.checkIdle(iterStamp)) { if (handler.checkIdle(idleStamp)) {
// this will queue the connection for closure on our next tick // this will queue the connection for closure on our next tick
handler.becameIdle(); handler.becameIdle();
} }
@@ -217,7 +218,7 @@ public abstract class ConnectionManager extends LoopingThread
// create a new authing connection object to manage the authentication of this client // create a new authing connection object to manage the authentication of this client
// connection and register it with our selection set // connection and register it with our selection set
channel.configureBlocking(false); channel.configureBlocking(false);
conn.init(this, channel, System.currentTimeMillis(), _idleTime); conn.init(this, channel, System.currentTimeMillis());
conn.selkey = register(channel, SelectionKey.OP_READ, conn); conn.selkey = register(channel, SelectionKey.OP_READ, conn);
_handlers.put(conn.selkey, conn); _handlers.put(conn.selkey, conn);
synchronized (this) { synchronized (this) {
@@ -22,35 +22,34 @@
package com.threerings.nio.conman; package com.threerings.nio.conman;
/** /**
* When a network event occurs, the connection manager calls the net event * When a network event occurs, the connection manager calls the net event handler associated with
* handler associated with that channel to process the event. There are * that channel to process the event. There are only a few handlers (and probably only ever will
* only a few handlers (and probably only ever will be): the one that * be): the one that accepts new connections, the one that deals with a connection while the client
* accepts new connections, the one that deals with a connection while the * is authenticating and the one that processes messages from authenticated connections.
* client is authenticating and the one that processes messages from
* authenticated connections.
* *
* <p> Using this interface prevents us from having to do a bunch of * <p> Using this interface prevents us from having to do a bunch of inefficient and ugly
* inefficient and ugly comparisons; instead we can call through an * comparisons; instead we can call through an interface method to the proper code.
* interface method to the proper code.
*/ */
public interface NetEventHandler public interface NetEventHandler
{ {
/** /**
* Called when a network event has occurred on this handler's source. * Called when a network event has occurred on this handler's source.
* *
* @return the number of bytes read from the network as a result of * @return the number of bytes read from the network as a result of handling this event.
* handling this event.
*/ */
int handleEvent (long when); int handleEvent (long when);
/** /**
* Called to ensure that this channel has not been idle for longer * Called to ensure that this channel has not been idle for longer than is possible in happily
* than is possible in happily operating circumstances. * operating circumstances.
* *
* @return true if the handler is idle (in which case it will be * @param idleStamp if the handler's last event occurred more recently than this timestamp, it
* closed shortly), false if it is not. * should return false, otherwise true.
*
* @return true if the handler is idle (in which case it will be closed shortly), false if it
* is not.
*/ */
boolean checkIdle (long now); boolean checkIdle (long idleStamp);
/** /**
* Called if the handler is deemed to be idle. Should shutdown any associated connection and * Called if the handler is deemed to be idle. Should shutdown any associated connection and
@@ -115,7 +115,7 @@ public class ServerSocketChannelAcceptor
// claim nothing // claim nothing
return 0; return 0;
} }
public boolean checkIdle (long now) { public boolean checkIdle (long idleStamp) {
return false; // we're never idle return false; // we're never idle
} }
public void becameIdle () { public void becameIdle () {
@@ -90,8 +90,8 @@ public class DatagramChannelReader
public int handleEvent (long when) { public int handleEvent (long when) {
return _conMan.handleDatagram(channel, when); return _conMan.handleDatagram(channel, when);
} }
public boolean checkIdle (long now) { public boolean checkIdle (long idleStamp) {
return false;// Can't be idle return false; // we can't be idle
} }
public void becameIdle () {} public void becameIdle () {}
}); });
@@ -60,11 +60,10 @@ public class PresentsConnection extends Connection
* {@link PresentsConnectionManager} as <code>cmgr</code>. * {@link PresentsConnectionManager} as <code>cmgr</code>.
*/ */
@Override @Override
public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp, public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp)
long idleTime)
throws IOException throws IOException
{ {
super.init(cmgr, channel, createStamp, idleTime); super.init(cmgr, channel, createStamp);
_pcmgr = (PresentsConnectionManager)cmgr; _pcmgr = (PresentsConnectionManager)cmgr;
} }
@@ -307,7 +307,7 @@ public class PresentsConnectionManager extends ConnectionManager
// have the non-blocking connect process started // have the non-blocking connect process started
SocketChannel sockchan = SocketChannel.open(); SocketChannel sockchan = SocketChannel.open();
sockchan.configureBlocking(false); sockchan.configureBlocking(false);
conn.init(this, sockchan, System.currentTimeMillis(), _idleTime); conn.init(this, sockchan, System.currentTimeMillis());
_connectq.append(Tuple.newTuple(conn, new InetSocketAddress(hostname, port))); _connectq.append(Tuple.newTuple(conn, new InetSocketAddress(hostname, port)));
} }
@@ -346,8 +346,8 @@ public class PresentsConnectionManager extends ConnectionManager
} }
return 0; return 0;
} }
public boolean checkIdle (long now) { public boolean checkIdle (long idleStamp) {
return conn.checkIdle(now); return conn.checkIdle(idleStamp);
} }
public void becameIdle () { public void becameIdle () {
handleError(new IOException("Pending connection became idle.")); handleError(new IOException("Pending connection became idle."));
@@ -452,7 +452,7 @@ public class PresentsConnectionManager extends ConnectionManager
// construct a new running connection to handle this connections network traffic // construct a new running connection to handle this connections network traffic
// from here on out // from here on out
PresentsConnection rconn = new PresentsConnection(); PresentsConnection rconn = new PresentsConnection();
rconn.init(this, conn.getChannel(), iterStamp, _idleTime); rconn.init(this, conn.getChannel(), iterStamp);
rconn.selkey = conn.selkey; rconn.selkey = conn.selkey;
// we need to keep using the same object input and output streams from the // we need to keep using the same object input and output streams from the