Revamped the way network stats are tracked so that they are all monotonically

increasing integers. Added tracking for connect and disconnect events.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4324 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2006-08-15 00:12:42 +00:00
parent cc4ed0b9d9
commit f40325fa67
2 changed files with 68 additions and 81 deletions
@@ -27,69 +27,49 @@ import com.threerings.io.SimpleStreamableObject;
* Used to track and report stats on the connection manager. * Used to track and report stats on the connection manager.
*/ */
public class ConMgrStats extends SimpleStreamableObject public class ConMgrStats extends SimpleStreamableObject
implements Cloneable
{ {
/** The current index into the history arrays. */ /** The size of the queue of waiting to auth sockets. This is a snapshot at
public int current; * the time the stats are requested. */
public int authQueueSize;
/** The size of the queue of waiting to auth sockets. */ /** The size of the queue of waiting to die sockets. This is a snapshot at
public int[] authQueueSize; * the time the stats are requested. */
public int deathQueueSize;
/** The size of the queue of waiting to die sockets. */ /** The outgoing queue size. This is a snapshot at the time the stats are
public int[] deathQueueSize; * requested. */
public int outQueueSize;
/** The outgoing queue size. */ /** The overflow queue size. This is a snapshot at the time the stats are
public int[] outQueueSize; * requested. */
public int overQueueSize;
/** The overflow queue size. */ /** The number of connection events since the server started up. */
public int[] overQueueSize; public int connects;
/** The number of bytes read. */ /** The number of disconnection events since the server started up. */
public int[] bytesIn; public int disconnects;
/** The number of bytes written. */ /** The number of bytes read since the server started up. */
public int[] bytesOut; public long bytesIn;
/** The number of messages read. */ /** The number of bytes written since the server started up. */
public int[] msgsIn; public long bytesOut;
/** The number of messages written. */ /** The number of messages read since the server started up. */
public int[] msgsOut; public int msgsIn;
/** Creates our historical arrays. */ /** The number of messages written since the server started up. */
public void init () public int msgsOut;
@Override // from Objecet
public Object clone ()
{ {
authQueueSize = new int[SLOTS]; try {
deathQueueSize = new int[SLOTS]; return super.clone();
outQueueSize = new int[SLOTS]; } catch (CloneNotSupportedException cnse) {
overQueueSize = new int[SLOTS]; throw new RuntimeException(cnse);
bytesIn = new int[SLOTS]; }
bytesOut = new int[SLOTS];
msgsIn = new int[SLOTS];
msgsOut = new int[SLOTS];
} }
/** Advances the currently accumulating bucket and clears its
* previous contents. */
public void increment ()
{
current = (current + 1) % authQueueSize.length;
authQueueSize[current] = 0;
deathQueueSize[current] = 0;
outQueueSize[current] = 0;
overQueueSize[current] = 0;
bytesIn[current] = 0;
bytesOut[current] = 0;
msgsIn[current] = 0;
msgsOut[current] = 0;
}
/**
* Returns the index of the most recently accumulated stats slot.
*/
public int mostRecent ()
{
return (current + SLOTS - 1) % SLOTS;
}
protected static final int SLOTS = 60;
} }
@@ -86,7 +86,7 @@ public class ConnectionManager extends LoopingThread
// create our stats record // create our stats record
_stats = new ConMgrStats(); _stats = new ConMgrStats();
_stats.init(); _lastStats = new ConMgrStats();
// register as a "state of server" reporter // register as a "state of server" reporter
PresentsServer.registerReporter(this); PresentsServer.registerReporter(this);
@@ -137,25 +137,23 @@ public class ConnectionManager extends LoopingThread
} }
/** /**
* Returns our current runtime statistics. When the stats are fetched * Returns our current runtime statistics. <em>Note:</em> don't call this
* the counters are rolled to the next bucket. 60 buckets are tracked. * method <em>too</em> frequently as it is synchronized and will contend
* <em>Note:</em> don't call this method <em>too</em> frequently (more * with the network I/O thread.
* often than once every few seconds or so) as it has to total things
* up and run a number of synchronized methods.
*/ */
public synchronized ConMgrStats getStats () public synchronized ConMgrStats getStats ()
{ {
// fill in our snapshot values // fill in our snapshot values
_stats.authQueueSize[_stats.current] = _authq.size(); _stats.authQueueSize = _authq.size();
_stats.deathQueueSize[_stats.current] = _deathq.size(); _stats.deathQueueSize = _deathq.size();
_stats.outQueueSize[_stats.current] = _outq.size(); _stats.outQueueSize = _outq.size();
if (_oflowqs.size() > 0) { if (_oflowqs.size() > 0) {
_stats.overQueueSize = 0;
for (OverflowQueue oq : _oflowqs.values()) { for (OverflowQueue oq : _oflowqs.values()) {
_stats.overQueueSize[_stats.current] += oq.size(); _stats.overQueueSize += oq.size();
} }
} }
_stats.increment(); return (ConMgrStats)_stats.clone();
return _stats;
} }
/** /**
@@ -204,21 +202,21 @@ public class ConnectionManager extends LoopingThread
public void appendReport ( public void appendReport (
StringBuilder report, long now, long sinceLast, boolean reset) StringBuilder report, long now, long sinceLast, boolean reset)
{ {
long bytesIn, bytesOut, msgsIn, msgsOut; ConMgrStats stats = getStats();
synchronized (this) { int connects = stats.connects - _lastStats.connects;
bytesIn = _bytesIn; int disconnects = stats.disconnects - _lastStats.disconnects;
bytesOut = _bytesOut; long bytesIn = stats.bytesIn - _lastStats.bytesIn;
msgsIn = _msgsIn; long bytesOut = stats.bytesOut - _lastStats.bytesOut;
msgsOut = _msgsOut; long msgsIn = stats.msgsIn - _lastStats.msgsIn;
if (reset) { long msgsOut = stats.msgsOut - _lastStats.msgsOut;
_bytesIn = 0L; if (reset) {
_bytesOut = 0L; _lastStats = stats;
_msgsIn = 0;
_msgsOut = 0;
}
} }
report.append("* presents.net.ConnectionManager:\n"); report.append("* presents.net.ConnectionManager:\n");
report.append("- Network connections: ");
report.append(connects).append(" connects, ");
report.append(disconnects).append(" disconnects\n");
report.append("- Network input: "); report.append("- Network input: ");
report.append(bytesIn).append(" bytes, "); report.append(bytesIn).append(" bytes, ");
report.append(msgsIn).append(" msgs, "); report.append(msgsIn).append(" msgs, ");
@@ -520,12 +518,12 @@ public class ConnectionManager extends LoopingThread
if (got != 0) { if (got != 0) {
synchronized (this) { synchronized (this) {
_bytesIn += got; _bytesIn += got;
_stats.bytesIn[_stats.current] += got; _stats.bytesIn += got;
// we know that the handlers only report having // we know that the handlers only report having
// read bytes when they have a whole message, so // read bytes when they have a whole message, so
// we can count thusly // we can count thusly
_msgsIn++; _msgsIn++;
_stats.msgsIn[_stats.current]++; _stats.msgsIn++;
} }
} }
@@ -621,8 +619,8 @@ public class ConnectionManager extends LoopingThread
{ {
_msgsOut += msgs; _msgsOut += msgs;
_bytesOut += bytes; _bytesOut += bytes;
_stats.msgsOut[_stats.current] += msgs; _stats.msgsOut += msgs;
_stats.bytesOut[_stats.current] += bytes; _stats.bytesOut += bytes;
} }
// documentation inherited // documentation inherited
@@ -686,6 +684,9 @@ public class ConnectionManager extends LoopingThread
SelectionKey selkey = selchan.register( SelectionKey selkey = selchan.register(
_selector, SelectionKey.OP_READ); _selector, SelectionKey.OP_READ);
_handlers.put(selkey, new AuthingConnection(this, selkey, channel)); _handlers.put(selkey, new AuthingConnection(this, selkey, channel));
synchronized (this) {
_stats.connects++;
}
return; return;
} catch (IOException ioe) { } catch (IOException ioe) {
@@ -754,6 +755,9 @@ public class ConnectionManager extends LoopingThread
// removed from the Selector when the socket is closed) // removed from the Selector when the socket is closed)
_handlers.remove(conn.getSelectionKey()); _handlers.remove(conn.getSelectionKey());
_oflowqs.remove(conn); _oflowqs.remove(conn);
synchronized (this) {
_stats.disconnects++;
}
// let our observers know what's up // let our observers know what's up
notifyObservers(CONNECTION_FAILED, conn, ioe, null); notifyObservers(CONNECTION_FAILED, conn, ioe, null);
@@ -914,6 +918,9 @@ public class ConnectionManager extends LoopingThread
/** Our current runtime stats. */ /** Our current runtime stats. */
protected ConMgrStats _stats; protected ConMgrStats _stats;
/** A snapshot of our runtime stats as of our last report. */
protected ConMgrStats _lastStats;
/** A runnable to execute when the connection manager thread exits. */ /** A runnable to execute when the connection manager thread exits. */
protected volatile Runnable _onExit; protected volatile Runnable _onExit;