From 74c2c7744306dda187244cf77d8cfdcc08d19793 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 16 Dec 2010 02:18:53 +0000 Subject: [PATCH] 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 --- .../com/threerings/nio/conman/Connection.java | 13 +++----- .../nio/conman/ConnectionManager.java | 5 +-- .../nio/conman/NetEventHandler.java | 31 +++++++++---------- .../conman/ServerSocketChannelAcceptor.java | 2 +- .../server/net/DatagramChannelReader.java | 4 +-- .../server/net/PresentsConnection.java | 5 ++- .../server/net/PresentsConnectionManager.java | 8 ++--- 7 files changed, 31 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/threerings/nio/conman/Connection.java b/src/main/java/com/threerings/nio/conman/Connection.java index a230e6586..f2ebc4cc1 100644 --- a/src/main/java/com/threerings/nio/conman/Connection.java +++ b/src/main/java/com/threerings/nio/conman/Connection.java @@ -45,14 +45,12 @@ public abstract class Connection implements NetEventHandler * @param channel The socket channel from which we'll be reading messages. * @param createStamp The time at which this connection was created. */ - public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp, - long idleTime) + public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp) throws IOException { _cmgr = cmgr; _channel = channel; _lastEvent = createStamp; - _idleTime = idleTime; _connectionId = ++_lastConnectionId; } @@ -147,15 +145,14 @@ public abstract class Connection implements NetEventHandler } // from interface NetEventHandler - public boolean checkIdle (long now) + public boolean checkIdle (long idleStamp) { - long idleMillis = now - _lastEvent; - if (idleMillis < _idleTime) { + if (_lastEvent > idleStamp) { return false; } if (!isClosed()) { log.info("Disconnecting non-communicative client", - "conn", this, "idle", idleMillis + "ms"); + "conn", this, "idle", (idleStamp - _lastEvent) + "ms"); } return true; } @@ -200,8 +197,6 @@ public abstract class Connection implements NetEventHandler protected int _connectionId; - protected long _idleTime; - /** The last connection id assigned. */ protected static int _lastConnectionId; } diff --git a/src/main/java/com/threerings/nio/conman/ConnectionManager.java b/src/main/java/com/threerings/nio/conman/ConnectionManager.java index 316686572..d81853eef 100644 --- a/src/main/java/com/threerings/nio/conman/ConnectionManager.java +++ b/src/main/java/com/threerings/nio/conman/ConnectionManager.java @@ -171,8 +171,9 @@ public abstract class ConnectionManager extends LoopingThread } // close connections that have had no network traffic for too long + long idleStamp = iterStamp - _idleTime; for (NetEventHandler handler : _handlers.values()) { - if (handler.checkIdle(iterStamp)) { + if (handler.checkIdle(idleStamp)) { // this will queue the connection for closure on our next tick 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 // connection and register it with our selection set channel.configureBlocking(false); - conn.init(this, channel, System.currentTimeMillis(), _idleTime); + conn.init(this, channel, System.currentTimeMillis()); conn.selkey = register(channel, SelectionKey.OP_READ, conn); _handlers.put(conn.selkey, conn); synchronized (this) { diff --git a/src/main/java/com/threerings/nio/conman/NetEventHandler.java b/src/main/java/com/threerings/nio/conman/NetEventHandler.java index e85c560bf..b716738ce 100644 --- a/src/main/java/com/threerings/nio/conman/NetEventHandler.java +++ b/src/main/java/com/threerings/nio/conman/NetEventHandler.java @@ -22,35 +22,34 @@ package com.threerings.nio.conman; /** - * When a network event occurs, the connection manager calls the net event - * handler associated with that channel to process the event. There are - * only a few handlers (and probably only ever will be): the one that - * accepts new connections, the one that deals with a connection while the - * client is authenticating and the one that processes messages from - * authenticated connections. + * When a network event occurs, the connection manager calls the net event handler associated with + * that channel to process the event. There are only a few handlers (and probably only ever will + * be): the one that accepts new connections, the one that deals with a connection while the client + * is authenticating and the one that processes messages from authenticated connections. * - *

Using this interface prevents us from having to do a bunch of - * inefficient and ugly comparisons; instead we can call through an - * interface method to the proper code. + *

Using this interface prevents us from having to do a bunch of inefficient and ugly + * comparisons; instead we can call through an interface method to the proper code. */ public interface NetEventHandler { /** * 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 - * handling this event. + * @return the number of bytes read from the network as a result of handling this event. */ int handleEvent (long when); /** - * Called to ensure that this channel has not been idle for longer - * than is possible in happily operating circumstances. + * Called to ensure that this channel has not been idle for longer than is possible in happily + * operating circumstances. * - * @return true if the handler is idle (in which case it will be - * closed shortly), false if it is not. + * @param idleStamp if the handler's last event occurred more recently than this timestamp, it + * 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 diff --git a/src/main/java/com/threerings/nio/conman/ServerSocketChannelAcceptor.java b/src/main/java/com/threerings/nio/conman/ServerSocketChannelAcceptor.java index f53f0fcb5..cd2d6f636 100644 --- a/src/main/java/com/threerings/nio/conman/ServerSocketChannelAcceptor.java +++ b/src/main/java/com/threerings/nio/conman/ServerSocketChannelAcceptor.java @@ -115,7 +115,7 @@ public class ServerSocketChannelAcceptor // claim nothing return 0; } - public boolean checkIdle (long now) { + public boolean checkIdle (long idleStamp) { return false; // we're never idle } public void becameIdle () { diff --git a/src/main/java/com/threerings/presents/server/net/DatagramChannelReader.java b/src/main/java/com/threerings/presents/server/net/DatagramChannelReader.java index ac52bec77..96b70869b 100644 --- a/src/main/java/com/threerings/presents/server/net/DatagramChannelReader.java +++ b/src/main/java/com/threerings/presents/server/net/DatagramChannelReader.java @@ -90,8 +90,8 @@ public class DatagramChannelReader public int handleEvent (long when) { return _conMan.handleDatagram(channel, when); } - public boolean checkIdle (long now) { - return false;// Can't be idle + public boolean checkIdle (long idleStamp) { + return false; // we can't be idle } public void becameIdle () {} }); diff --git a/src/main/java/com/threerings/presents/server/net/PresentsConnection.java b/src/main/java/com/threerings/presents/server/net/PresentsConnection.java index bcc18bd59..e5fedfe85 100644 --- a/src/main/java/com/threerings/presents/server/net/PresentsConnection.java +++ b/src/main/java/com/threerings/presents/server/net/PresentsConnection.java @@ -60,11 +60,10 @@ public class PresentsConnection extends Connection * {@link PresentsConnectionManager} as cmgr. */ @Override - public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp, - long idleTime) + public void init (ConnectionManager cmgr, SocketChannel channel, long createStamp) throws IOException { - super.init(cmgr, channel, createStamp, idleTime); + super.init(cmgr, channel, createStamp); _pcmgr = (PresentsConnectionManager)cmgr; } diff --git a/src/main/java/com/threerings/presents/server/net/PresentsConnectionManager.java b/src/main/java/com/threerings/presents/server/net/PresentsConnectionManager.java index 1efb3529c..e7f5925fc 100644 --- a/src/main/java/com/threerings/presents/server/net/PresentsConnectionManager.java +++ b/src/main/java/com/threerings/presents/server/net/PresentsConnectionManager.java @@ -307,7 +307,7 @@ public class PresentsConnectionManager extends ConnectionManager // have the non-blocking connect process started SocketChannel sockchan = SocketChannel.open(); 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))); } @@ -346,8 +346,8 @@ public class PresentsConnectionManager extends ConnectionManager } return 0; } - public boolean checkIdle (long now) { - return conn.checkIdle(now); + public boolean checkIdle (long idleStamp) { + return conn.checkIdle(idleStamp); } public void becameIdle () { 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 // from here on out PresentsConnection rconn = new PresentsConnection(); - rconn.init(this, conn.getChannel(), iterStamp, _idleTime); + rconn.init(this, conn.getChannel(), iterStamp); rconn.selkey = conn.selkey; // we need to keep using the same object input and output streams from the