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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user