Add IncomingPacketsProcessedCount stat for diagnostics.

Also puts some packet processing counts in a container named after the scene so that stats can be collected from more than one scene.
0.7.4-extended
Justin Clark-Casey (justincc) 2012-11-15 01:14:18 +00:00
parent 4fe042aa7f
commit b7c1a37676
2 changed files with 97 additions and 39 deletions

View File

@ -70,6 +70,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void AddScene(IScene scene) public void AddScene(IScene scene)
{ {
m_udpServer.AddScene(scene); m_udpServer.AddScene(scene);
StatsManager.RegisterStat(
new Stat(
"IncomingPacketsProcessedCount",
"Number of inbound UDP packets processed",
"Number of inbound UDP packets processed",
"",
"clientstack",
scene.Name,
StatType.Pull,
stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
StatVerbosity.Debug));
} }
public bool HandlesRegion(Location x) public bool HandlesRegion(Location x)
@ -170,6 +182,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Pool<IncomingPacket> m_incomingPacketPool; private Pool<IncomingPacket> m_incomingPacketPool;
/// <summary>
/// Stat for number of packets in the main pool awaiting use.
/// </summary>
private Stat m_poolCountStat;
/// <summary>
/// Stat for number of packets in the inbound packet pool awaiting use.
/// </summary>
private Stat m_incomingPacketPoolStat; private Stat m_incomingPacketPoolStat;
private int m_defaultRTO = 0; private int m_defaultRTO = 0;
@ -342,20 +362,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
m_incomingPacketPoolStat
= new Stat(
"IncomingPacketPoolCount",
"Objects within incoming packet pool",
"The number of objects currently stored within the incoming packet pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_incomingPacketPoolStat);
return true; return true;
} }
@ -378,6 +384,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false; return false;
} }
/// <summary>
/// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
/// stats.
/// </summary>
private void EnablePoolStats()
{
m_poolCountStat
= new Stat(
"UDPPacketBufferPoolCount",
"Objects within the UDPPacketBuffer pool",
"The number of objects currently stored within the UDPPacketBuffer pool",
"",
"clientstack",
m_scene.Name,
StatType.Pull,
stat => stat.Value = Pool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_poolCountStat);
m_incomingPacketPoolStat
= new Stat(
"IncomingPacketPoolCount",
"Objects within incoming packet pool",
"The number of objects currently stored within the incoming packet pool",
"",
"clientstack",
m_scene.Name,
StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_incomingPacketPoolStat);
}
/// <summary>
/// Disables pool stats.
/// </summary>
private void DisablePoolStats()
{
StatsManager.DeregisterStat(m_poolCountStat);
m_poolCountStat = null;
StatsManager.DeregisterStat(m_incomingPacketPoolStat);
m_incomingPacketPoolStat = null;
}
/// <summary> /// <summary>
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
/// </summary> /// </summary>
@ -416,6 +469,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene; m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle); m_location = new Location(m_scene.RegionInfo.RegionHandle);
// We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
// scene name
if (UsePools)
EnablePoolStats();
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"Debug", "Debug",
@ -505,12 +563,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (enabled == "on") if (enabled == "on")
{ {
if (EnablePools()) if (EnablePools())
{
EnablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
}
} }
else if (enabled == "off") else if (enabled == "off")
{ {
if (DisablePools()) if (DisablePools())
{
DisablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
}
} }
else else
{ {
@ -1556,6 +1620,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int npacksSent = 0; private int npacksSent = 0;
private int npackNotSent = 0; private int npackNotSent = 0;
/// <summary>
/// Number of inbound packets processed since startup.
/// </summary>
public long IncomingPacketsProcessed { get; private set; }
private void MonitoredClientOutgoingPacketHandler(IClientAPI client) private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
{ {
nticks++; nticks++;
@ -1615,7 +1684,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
npacksSent++; npacksSent++;
} }
else else
{
npackNotSent++; npackNotSent++;
}
watch2.Stop(); watch2.Stop();
avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
@ -1623,7 +1694,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{
m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -1687,6 +1760,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
packet.Type, client.Name, m_scene.RegionInfo.RegionName); packet.Type, client.Name, m_scene.RegionInfo.RegionName);
} }
IncomingPacketsProcessed++;
} }
protected void LogoutHandler(IClientAPI client) protected void LogoutHandler(IClientAPI client)

View File

@ -60,16 +60,16 @@ namespace OpenMetaverse
/// <summary>Flag to process packets asynchronously or synchronously</summary> /// <summary>Flag to process packets asynchronously or synchronously</summary>
private bool m_asyncPacketHandling; private bool m_asyncPacketHandling;
/// <summary>
/// Pool to use for handling data. May be null if UsePools = false;
/// </summary>
protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool;
/// <summary> /// <summary>
/// Are we to use object pool(s) to reduce memory churn when receiving data? /// Are we to use object pool(s) to reduce memory churn when receiving data?
/// </summary> /// </summary>
public bool UsePools { get; protected set; } public bool UsePools { get; protected set; }
/// <summary>
/// Pool to use for handling data. May be null if UsePools = false;
/// </summary>
protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; }
/// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
public bool IsRunningInbound { get; private set; } public bool IsRunningInbound { get; private set; }
@ -77,8 +77,6 @@ namespace OpenMetaverse
/// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks> /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
public bool IsRunningOutbound { get; private set; } public bool IsRunningOutbound { get; private set; }
private Stat m_poolCountStat;
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
@ -182,21 +180,7 @@ namespace OpenMetaverse
{ {
if (!UsePools) if (!UsePools)
{ {
m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
m_poolCountStat
= new Stat(
"UDPPacketBufferPoolCount",
"Objects within the UDPPacketBuffer pool",
"The number of objects currently stored within the UDPPacketBuffer pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => stat.Value = m_pool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_poolCountStat);
UsePools = true; UsePools = true;
@ -211,7 +195,6 @@ namespace OpenMetaverse
if (UsePools) if (UsePools)
{ {
UsePools = false; UsePools = false;
StatsManager.DeregisterStat(m_poolCountStat);
// We won't null out the pool to avoid a race condition with code that may be in the middle of using it. // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
@ -226,7 +209,7 @@ namespace OpenMetaverse
UDPPacketBuffer buf; UDPPacketBuffer buf;
if (UsePools) if (UsePools)
buf = m_pool.GetObject(); buf = Pool.GetObject();
else else
buf = new UDPPacketBuffer(); buf = new UDPPacketBuffer();
@ -309,7 +292,7 @@ namespace OpenMetaverse
finally finally
{ {
if (UsePools) if (UsePools)
m_pool.ReturnObject(buffer); Pool.ReturnObject(buffer);
// Synchronous mode waits until the packet callback completes // Synchronous mode waits until the packet callback completes
// before starting the receive to fetch another packet // before starting the receive to fetch another packet