Don't let presents' ping interval into Connection

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6384 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Charlie Groves
2010-12-16 01:59:47 +00:00
parent 4d163ffd7f
commit 6a45fec4ea
5 changed files with 26 additions and 20 deletions
@@ -48,7 +48,7 @@ public class PolicyServer extends ConnectionManager
public PolicyServer (Lifecycle cycle) public PolicyServer (Lifecycle cycle)
throws IOException throws IOException
{ {
super(cycle); super(cycle, LATENCY_GRACE);
} }
/** /**
@@ -34,9 +34,6 @@ import java.nio.channels.SocketChannel;
*/ */
public abstract class Connection implements NetEventHandler public abstract class Connection implements NetEventHandler
{ {
/** The number of milliseconds of idle upstream that are allowed to elapse before the client
* sends a ping message to the server to let it know that we're still alive. */
public static final long PING_INTERVAL = 60 * 1000L;
/** The key used by the NIO code to track this connection. */ /** The key used by the NIO code to track this connection. */
public SelectionKey selkey; public SelectionKey selkey;
@@ -48,12 +45,14 @@ 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;
} }
@@ -151,13 +150,13 @@ public abstract class Connection implements NetEventHandler
public boolean checkIdle (long now) public boolean checkIdle (long now)
{ {
long idleMillis = now - _lastEvent; long idleMillis = now - _lastEvent;
if (idleMillis < PING_INTERVAL + LATENCY_GRACE) { if (idleMillis < _idleTime) {
return false; return false;
} }
if (isClosed()) { if (!isClosed()) {
return true; log.info("Disconnecting non-communicative client",
"conn", this, "idle", idleMillis + "ms");
} }
log.info("Disconnecting non-communicative client", "conn", this, "idle", idleMillis + "ms");
return true; return true;
} }
@@ -201,10 +200,8 @@ 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;
/** The number of milliseconds beyond the ping interval that we allow a client's network
* connection to be idle before we forcibly disconnect them. */
protected static final long LATENCY_GRACE = 30 * 1000L;
} }
@@ -62,12 +62,13 @@ public abstract class ConnectionManager extends LoopingThread
/** /**
* Creates a connection manager instance. * Creates a connection manager instance.
*/ */
public ConnectionManager (Lifecycle cycle) public ConnectionManager (Lifecycle cycle, long idleTime)
throws IOException throws IOException
{ {
super("ConnectionManager"); super("ConnectionManager");
cycle.addComponent(this); cycle.addComponent(this);
_selector = Selector.open(); _selector = Selector.open();
_idleTime = idleTime;
} }
/** /**
@@ -216,7 +217,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()); conn.init(this, channel, System.currentTimeMillis(), _idleTime);
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) {
@@ -636,6 +637,8 @@ public abstract class ConnectionManager extends LoopingThread
@Inject(optional=true) @Named("presents.net.selectLoopTime") @Inject(optional=true) @Named("presents.net.selectLoopTime")
protected int _selectLoopTime = 100; protected int _selectLoopTime = 100;
protected final long _idleTime;
/** Used to denote asynchronous close requests. */ /** Used to denote asynchronous close requests. */
protected static final byte[] ASYNC_CLOSE_REQUEST = new byte[0]; protected static final byte[] ASYNC_CLOSE_REQUEST = new byte[0];
@@ -644,4 +647,8 @@ public abstract class ConnectionManager extends LoopingThread
/** Report our activity every 30 seconds. */ /** Report our activity every 30 seconds. */
protected static final long DEBUG_REPORT_INTERVAL = 30*1000L; protected static final long DEBUG_REPORT_INTERVAL = 30*1000L;
/** The number of milliseconds beyond the ping interval that we allow a client's network
* connection to be idle before we forcibly disconnect them. */
protected static final long LATENCY_GRACE = 30 * 1000L;
} }
@@ -60,10 +60,11 @@ 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); super.init(cmgr, channel, createStamp, idleTime);
_pcmgr = (PresentsConnectionManager)cmgr; _pcmgr = (PresentsConnectionManager)cmgr;
} }
@@ -51,6 +51,7 @@ import com.threerings.presents.annotation.AuthInvoker;
import com.threerings.presents.client.Client; import com.threerings.presents.client.Client;
import com.threerings.presents.data.PresentsConMgrStats; import com.threerings.presents.data.PresentsConMgrStats;
import com.threerings.presents.net.Message; import com.threerings.presents.net.Message;
import com.threerings.presents.net.PingRequest;
import com.threerings.presents.net.PongResponse; import com.threerings.presents.net.PongResponse;
import com.threerings.presents.net.Transport; import com.threerings.presents.net.Transport;
import com.threerings.presents.server.Authenticator; import com.threerings.presents.server.Authenticator;
@@ -76,7 +77,7 @@ public class PresentsConnectionManager extends ConnectionManager
public PresentsConnectionManager (Lifecycle cycle, ReportManager repmgr) public PresentsConnectionManager (Lifecycle cycle, ReportManager repmgr)
throws IOException throws IOException
{ {
super(cycle); super(cycle, LATENCY_GRACE + PingRequest.PING_INTERVAL);
repmgr.registerReporter(this); repmgr.registerReporter(this);
_stats = new PresentsConMgrStats(); _stats = new PresentsConMgrStats();
} }
@@ -306,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()); conn.init(this, sockchan, System.currentTimeMillis(), _idleTime);
_connectq.append(Tuple.newTuple(conn, new InetSocketAddress(hostname, port))); _connectq.append(Tuple.newTuple(conn, new InetSocketAddress(hostname, port)));
} }
@@ -451,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); rconn.init(this, conn.getChannel(), iterStamp, _idleTime);
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