From 30eea2618dcc0a43d1d4d764590100c19bd7c05d Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Fri, 22 Feb 2008 20:50:30 +0000
Subject: * Implement packet queue statistics * This will show the packets
waiting in each queue for each client logged into a region server * These are
displayed using 'show stats' on the region command line * This is in pursuit
of a memory leak. * This will require a prebuild
---
.../Framework/Statistics/SimExtraStatsReporter.cs | 95 ++++++++++++++++++++--
OpenSim/Region/ClientStack/ClientView.cs | 2 +-
OpenSim/Region/ClientStack/PacketQueue.cs | 37 ++++++++-
3 files changed, 124 insertions(+), 10 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs b/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs
index c8b8223..acf2ecb 100644
--- a/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs
+++ b/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs
@@ -26,12 +26,19 @@
*
*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+
using OpenSim.Framework;
+using OpenSim.Framework.Statistics.Interfaces;
+
+using libsecondlife;
namespace OpenSim.Framework.Statistics
{
public class SimExtraStatsReporter
- {
+ {
private long assetsInCache;
private long texturesInCache;
private long assetCacheMemoryUsage;
@@ -42,6 +49,12 @@ namespace OpenSim.Framework.Statistics
public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } }
public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } }
+ ///
+ /// Retain a dictionary of all packet queues stats reporters
+ ///
+ private IDictionary packetQueueStatsReporters
+ = new Dictionary();
+
public void AddAsset(AssetBase asset)
{
assetsInCache++;
@@ -56,19 +69,87 @@ namespace OpenSim.Framework.Statistics
texturesInCache++;
textureCacheMemoryUsage += image.Data.Length;
}
- }
+ }
+
+ ///
+ /// Register as a packet queue stats provider
+ ///
+ /// An agent LLUUID
+ ///
+ public void RegisterPacketQueueStatsProvider(LLUUID uuid, IPullStatsProvider provider)
+ {
+ lock (packetQueueStatsReporters)
+ {
+ packetQueueStatsReporters[uuid] = new PacketQueueStatsReporter(provider);
+ }
+ }
+
+ ///
+ /// Deregister a packet queue stats provider
+ ///
+ /// An agent LLUUID
+ public void DeregisterPacketQueueStatsProvider(LLUUID uuid)
+ {
+ lock (packetQueueStatsReporters)
+ {
+ packetQueueStatsReporters.Remove(uuid);
+ }
+ }
///
/// Report back collected statistical information.
///
///
public string Report()
- {
- return string.Format(
+ {
+ StringBuilder sb = new StringBuilder(Environment.NewLine);
+ sb.Append("PACKET QUEUE STATISTICS");
+ sb.Append(Environment.NewLine);
+ sb.Append(
+ string.Format(
@"Asset cache contains {0,6} assets using {1,10:0.000}K
-Texture cache contains {2,6} textures using {3,10:0.000}K",
- AssetsInCache, AssetCacheMemoryUsage / 1024.0,
- TexturesInCache, TextureCacheMemoryUsage / 1024.0);
+Texture cache contains {2,6} textures using {3,10:0.000}K" + Environment.NewLine,
+ AssetsInCache, AssetCacheMemoryUsage / 1024.0,
+ TexturesInCache, TextureCacheMemoryUsage / 1024.0));
+
+ sb.Append(Environment.NewLine);
+ sb.Append("PACKET QUEUE STATISTICS");
+ sb.Append(Environment.NewLine);
+ sb.Append("Agent UUID ");
+ sb.Append(" Send In Out Resend ");
+ sb.Append(" Land Wind Cloud Task Texture Asset");
+ sb.Append(Environment.NewLine);
+
+ foreach (LLUUID key in packetQueueStatsReporters.Keys)
+ {
+ sb.Append(string.Format("{0}: ", key));
+ sb.Append(packetQueueStatsReporters[key].Report());
+ sb.Append(Environment.NewLine);
+ }
+
+ return sb.ToString();
}
}
+
+ ///
+ /// Pull packet queue stats from packet queues and report
+ ///
+ public class PacketQueueStatsReporter
+ {
+ private IPullStatsProvider m_statsProvider;
+
+ public PacketQueueStatsReporter(IPullStatsProvider provider)
+ {
+ m_statsProvider = provider;
+ }
+
+ ///
+ /// Report back collected statistical information.
+ ///
+ ///
+ public string Report()
+ {
+ return m_statsProvider.GetStats();
+ }
+ }
}
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index 2cedc81..8bdbe89 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -317,7 +317,7 @@ namespace OpenSim.Region.ClientStack
// in it to process. It's an on-purpose threadlock though because
// without it, the clientloop will suck up all sim resources.
- m_packetQueue = new PacketQueue();
+ m_packetQueue = new PacketQueue(agentId);
RegisterLocalPacketHandlers();
diff --git a/OpenSim/Region/ClientStack/PacketQueue.cs b/OpenSim/Region/ClientStack/PacketQueue.cs
index 06ed32e..4673082 100644
--- a/OpenSim/Region/ClientStack/PacketQueue.cs
+++ b/OpenSim/Region/ClientStack/PacketQueue.cs
@@ -29,13 +29,16 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Timers;
+using libsecondlife;
using libsecondlife.Packets;
using OpenSim.Framework;
+using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Statistics.Interfaces;
using Timer=System.Timers.Timer;
namespace OpenSim.Region.ClientStack
{
- public class PacketQueue
+ public class PacketQueue : IPullStatsProvider
{
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -76,8 +79,10 @@ namespace OpenSim.Region.ClientStack
// private long LastThrottle;
// private long ThrottleInterval;
private Timer throttleTimer;
+
+ private LLUUID m_agentId;
- public PacketQueue()
+ public PacketQueue(LLUUID agentId)
{
// While working on this, the BlockingQueue had me fooled for a bit.
// The Blocking queue causes the thread to stop until there's something
@@ -116,6 +121,13 @@ namespace OpenSim.Region.ClientStack
// TIMERS needed for this
// LastThrottle = DateTime.Now.Ticks;
// ThrottleInterval = (long)(throttletimems/throttleTimeDivisor);
+
+ m_agentId = agentId;
+
+ if (StatsManager.SimExtraStats != null)
+ {
+ StatsManager.SimExtraStats.RegisterPacketQueueStatsProvider(m_agentId, this);
+ }
}
/* STANDARD QUEUE MANIPULATION INTERFACES */
@@ -214,6 +226,11 @@ namespace OpenSim.Region.ClientStack
{
m_enabled = false;
throttleTimer.Stop();
+
+ if (StatsManager.SimExtraStats != null)
+ {
+ StatsManager.SimExtraStats.DeregisterPacketQueueStatsProvider(m_agentId);
+ }
}
private void ResetCounters()
@@ -483,5 +500,21 @@ namespace OpenSim.Region.ClientStack
// effectively wiggling the slider causes things reset
ResetCounters();
}
+
+ // See IPullStatsProvider
+ public string GetStats()
+ {
+ return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
+ SendQueue.Count(),
+ IncomingPacketQueue.Count,
+ OutgoingPacketQueue.Count,
+ ResendOutgoingPacketQueue.Count,
+ LandOutgoingPacketQueue.Count,
+ WindOutgoingPacketQueue.Count,
+ CloudOutgoingPacketQueue.Count,
+ TaskOutgoingPacketQueue.Count,
+ TextureOutgoingPacketQueue.Count,
+ AssetOutgoingPacketQueue.Count);
+ }
}
}
--
cgit v1.1