Track various peer stats.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5760 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2009-04-29 22:10:31 +00:00
parent 2a4ac9b96a
commit a66c27a169
2 changed files with 109 additions and 10 deletions
@@ -23,6 +23,7 @@ package com.threerings.presents.peer.server;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -157,6 +158,43 @@ public abstract class PeerManager
protected abstract void execute (); protected abstract void execute ();
} }
/** Returned by {@link #getStats}. */
public static class Stats implements Cloneable
{
/** The number of locks this node has acquired. */
public long locksAcquired;
/** The number of milliseconds spent waiting to acquire locks. */
public long lockAcquireWait;
/** The number of locks this node has released. */
public long locksReleased;
/** The number of locks this node has had hijacked. */
public long locksHijacked;
/** The number of lock requests that have timed out. */
public long lockTimeouts;
/** The number of node actions we've invoked. */
public long nodeActionsInvoked;
/** The total number of messages received from all of our peers. This is updated on the
* conmgr thread which is why it's atomic. */
public AtomicLong peerMessagesIn = new AtomicLong(0);
/** The total number of messages sent to all of our peers. */
public long peerMessagesOut;
@Override public Stats clone () {
try {
return (Stats)super.clone();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/** /**
* Creates an uninitialized peer manager. * Creates an uninitialized peer manager.
*/ */
@@ -359,6 +397,10 @@ public abstract class PeerManager
if (!invoked && onDropped != null) { if (!invoked && onDropped != null) {
onDropped.run(); onDropped.run();
} }
if (invoked) {
_stats.nodeActionsInvoked++; // stats!
}
} }
/** /**
@@ -497,8 +539,7 @@ public abstract class PeerManager
public void requestCompleted (String result) { public void requestCompleted (String result) {
if (result == null) { if (result == null) {
if (_suboids.isEmpty()) { if (_suboids.isEmpty()) {
_nodeobj.addToLocks(lock); lockAcquired(lock, 0L, listener);
listener.requestCompleted(_nodeName);
} else { } else {
_locks.put(lock, new LockHandler(lock, true, listener)); _locks.put(lock, new LockHandler(lock, true, listener));
} }
@@ -521,8 +562,7 @@ public abstract class PeerManager
public void requestCompleted (String result) { public void requestCompleted (String result) {
if (_nodeName.equals(result)) { if (_nodeName.equals(result)) {
if (_suboids.isEmpty()) { if (_suboids.isEmpty()) {
_nodeobj.removeFromLocks(lock); lockReleased(lock, listener);
listener.requestCompleted(null);
} else { } else {
_locks.put(lock, new LockHandler(lock, false, listener)); _locks.put(lock, new LockHandler(lock, false, listener));
} }
@@ -705,11 +745,20 @@ public abstract class PeerManager
_nodeobj.setCacheData(new NodeObject.CacheData(cache, data)); _nodeobj.setCacheData(new NodeObject.CacheData(cache, data));
} }
/**
* Returns a snapshot of runtime statistics tracked by the peer manager.
*/
public Stats getStats ()
{
return _stats.clone();
}
// from interface ShutdownManager.Shutdowner // from interface ShutdownManager.Shutdowner
public void shutdown () public void shutdown ()
{ {
if (_nodeName == null) { // sanity check if (_nodeName == null) { // sanity check
throw new IllegalStateException("Shutting down PeerManager that was never initialized."); throw new IllegalStateException(
"Shutting down PeerManager that was never initialized.");
} }
// clear out our invocation service // clear out our invocation service
@@ -952,6 +1001,7 @@ public abstract class PeerManager
protected void droppedLock (final NodeObject.Lock lock) protected void droppedLock (final NodeObject.Lock lock)
{ {
_nodeobj.removeFromLocks(lock); _nodeobj.removeFromLocks(lock);
_stats.locksHijacked++;
_dropobs.apply(new ObserverList.ObserverOp<DroppedLockObserver>() { _dropobs.apply(new ObserverList.ObserverOp<DroppedLockObserver>() {
public boolean apply (DroppedLockObserver observer) { public boolean apply (DroppedLockObserver observer) {
observer.droppedLock(lock); observer.droppedLock(lock);
@@ -1021,6 +1071,8 @@ public abstract class PeerManager
// this may be the first we've heard of this guy, so let's refresh our peers and // this may be the first we've heard of this guy, so let's refresh our peers and
// potentially connect right back to him // potentially connect right back to him
refreshPeers(); refreshPeers();
// pass our stats record in so that it can count up messages in/out
session.setStats(_stats);
} }
/** /**
@@ -1028,7 +1080,7 @@ public abstract class PeerManager
*/ */
protected void peerEndedSession (PeerSession session) protected void peerEndedSession (PeerSession session)
{ {
// nothing presently // nada
} }
/** /**
@@ -1083,6 +1135,21 @@ public abstract class PeerManager
} }
} }
protected void lockAcquired (NodeObject.Lock lock, long wait, ResultListener<String> listener)
{
_nodeobj.addToLocks(lock);
_stats.locksAcquired++;
_stats.lockAcquireWait += wait;
listener.requestCompleted(_nodeName);
}
protected void lockReleased (NodeObject.Lock lock, ResultListener<String> listener)
{
_nodeobj.removeFromLocks(lock);
_stats.locksReleased++;
listener.requestCompleted(null);
}
/** /**
* Handles a lock in a state of resolution. * Handles a lock in a state of resolution.
*/ */
@@ -1118,6 +1185,7 @@ public abstract class PeerManager
public void expired () { public void expired () {
log.warning("Lock handler timed out, acting anyway", "lock", _lock, log.warning("Lock handler timed out, acting anyway", "lock", _lock,
"acquire", _acquire); "acquire", _acquire);
_stats.lockTimeouts++;
activate(); activate();
} }
}).schedule(LOCK_TIMEOUT); }).schedule(LOCK_TIMEOUT);
@@ -1198,6 +1266,7 @@ public abstract class PeerManager
{ {
cancel(); cancel();
_locks.remove(_lock); _locks.remove(_lock);
_stats.locksHijacked++;
listeners.requestCompleted(nodeName); listeners.requestCompleted(nodeName);
} }
@@ -1264,11 +1333,9 @@ public abstract class PeerManager
{ {
_locks.remove(_lock); _locks.remove(_lock);
if (_acquire) { if (_acquire) {
_nodeobj.addToLocks(_lock); lockAcquired(_lock, System.currentTimeMillis() - _startStamp, listeners);
listeners.requestCompleted(_nodeName);
} else { } else {
_nodeobj.removeFromLocks(_lock); lockReleased(_lock, listeners);
listeners.requestCompleted(null);
} }
} }
@@ -1287,6 +1354,7 @@ public abstract class PeerManager
protected boolean _acquire; protected boolean _acquire;
protected ArrayIntSet _remoids; protected ArrayIntSet _remoids;
protected Interval _timeout; protected Interval _timeout;
protected long _startStamp = System.currentTimeMillis();
} }
// (this need not use a runqueue as all it will do is post an invoker unit) // (this need not use a runqueue as all it will do is post an invoker unit)
@@ -1319,6 +1387,9 @@ public abstract class PeerManager
/** Locks in the process of resolution. */ /** Locks in the process of resolution. */
protected Map<NodeObject.Lock, LockHandler> _locks = Maps.newHashMap(); protected Map<NodeObject.Lock, LockHandler> _locks = Maps.newHashMap();
/** Used to track runtime statistics. */
protected Stats _stats = new Stats();
// our service dependencies // our service dependencies
@Inject protected ConnectionManager _conmgr; @Inject protected ConnectionManager _conmgr;
@Inject protected ClientManager _clmgr; @Inject protected ClientManager _clmgr;
@@ -27,6 +27,8 @@ import com.samskivert.util.Throttle;
import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObject;
import com.threerings.presents.net.BootstrapData; import com.threerings.presents.net.BootstrapData;
import com.threerings.presents.net.DownstreamMessage;
import com.threerings.presents.net.Message;
import com.threerings.presents.peer.data.NodeObject; import com.threerings.presents.peer.data.NodeObject;
import com.threerings.presents.peer.net.PeerBootstrapData; import com.threerings.presents.peer.net.PeerBootstrapData;
import com.threerings.presents.server.PresentsSession; import com.threerings.presents.server.PresentsSession;
@@ -47,6 +49,21 @@ public class PeerSession extends PresentsSession
_peermgr = peermgr; _peermgr = peermgr;
} }
/**
* Passes in a stats instance that this peer can use to note when it trafficks.
*/
public void setStats (PeerManager.Stats stats)
{
_stats = stats;
}
@Override // from PresentsSession
public void handleMessage (Message message)
{
super.handleMessage(message);
_stats.peerMessagesIn.incrementAndGet();
}
@Override // from PresentsSession @Override // from PresentsSession
protected BootstrapData createBootstrapData () protected BootstrapData createBootstrapData ()
{ {
@@ -98,6 +115,16 @@ public class PeerSession extends PresentsSession
_peermgr.peerEndedSession(this); _peermgr.peerEndedSession(this);
} }
@Override // from PresentsSession
protected final boolean postMessage (DownstreamMessage msg)
{
if (!super.postMessage(msg)) {
return false;
}
_stats.peerMessagesOut++;
return true;
}
@Override // from PresentsSession @Override // from PresentsSession
protected void subscribedToObject (DObject object) protected void subscribedToObject (DObject object)
{ {
@@ -134,6 +161,7 @@ public class PeerSession extends PresentsSession
} }
protected PeerManager _peermgr; protected PeerManager _peermgr;
protected PeerManager.Stats _stats;
protected int _cloid; protected int _cloid;
protected long _nextThrottleWarning; protected long _nextThrottleWarning;
} }