Add object count stats for new IncomingPacket and UDPPacketBuffer pools if they are enabled. Add count stats for existing LLUDP pool.
This introduces a pull stat type in addition to the push stat type. A pull stat takes a method on construction which knows how to update the stat on request. In this way, special interfaces for pull stat collection are not necessary.0.7.4-extended
parent
f39c2cd714
commit
5413bfec30
|
@ -248,6 +248,19 @@ namespace OpenSim.Framework.Monitoring
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stat type.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A push stat is one which is continually updated and so it's value can simply by read.
|
||||||
|
/// A pull stat is one where reading the value triggers a collection method - the stat is not continually updated.
|
||||||
|
/// </remarks>
|
||||||
|
public enum StatType
|
||||||
|
{
|
||||||
|
Push,
|
||||||
|
Pull
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verbosity of stat.
|
/// Verbosity of stat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -285,29 +298,65 @@ namespace OpenSim.Framework.Monitoring
|
||||||
/// </value>
|
/// </value>
|
||||||
public string Container { get; private set; }
|
public string Container { get; private set; }
|
||||||
|
|
||||||
|
public StatType StatType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Action used to update this stat when the value is requested if it's a pull type.
|
||||||
|
/// </summary>
|
||||||
|
public Action<Stat> PullAction { get; private set; }
|
||||||
|
|
||||||
public StatVerbosity Verbosity { get; private set; }
|
public StatVerbosity Verbosity { get; private set; }
|
||||||
public string ShortName { get; private set; }
|
public string ShortName { get; private set; }
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
public string Description { get; private set; }
|
public string Description { get; private set; }
|
||||||
public virtual string UnitName { get; private set; }
|
public virtual string UnitName { get; private set; }
|
||||||
|
|
||||||
public virtual double Value { get; set; }
|
public virtual double Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Asking for an update here means that the updater cannot access this value without infinite recursion.
|
||||||
|
// XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
|
||||||
|
// called by the pull action and just return the value.
|
||||||
|
if (StatType == StatType.Pull)
|
||||||
|
PullAction(this);
|
||||||
|
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double m_value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
|
/// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
|
||||||
/// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
|
/// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
|
||||||
|
/// <param name='description'>Description of stat</param>
|
||||||
/// <param name='unitName'>
|
/// <param name='unitName'>
|
||||||
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
|
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
|
||||||
/// e.g. " frames"
|
/// e.g. " frames"
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
|
/// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
|
||||||
/// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
|
/// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
|
||||||
|
/// <param name='type'>Push or pull</param>
|
||||||
|
/// <param name='pullAction'>Pull stats need an action to update the stat on request. Push stats should set null here.</param>
|
||||||
/// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
|
/// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
|
||||||
/// <param name='description'>Description of stat</param>
|
|
||||||
public Stat(
|
public Stat(
|
||||||
string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
|
string shortName,
|
||||||
|
string name,
|
||||||
|
string description,
|
||||||
|
string unitName,
|
||||||
|
string category,
|
||||||
|
string container,
|
||||||
|
StatType type,
|
||||||
|
Action<Stat> pullAction,
|
||||||
|
StatVerbosity verbosity)
|
||||||
{
|
{
|
||||||
if (StatsManager.SubCommands.Contains(category))
|
if (StatsManager.SubCommands.Contains(category))
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
@ -315,11 +364,18 @@ namespace OpenSim.Framework.Monitoring
|
||||||
|
|
||||||
ShortName = shortName;
|
ShortName = shortName;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
Description = description;
|
||||||
UnitName = unitName;
|
UnitName = unitName;
|
||||||
Category = category;
|
Category = category;
|
||||||
Container = container;
|
Container = container;
|
||||||
|
StatType = type;
|
||||||
|
|
||||||
|
if (StatType == StatType.Push && pullAction != null)
|
||||||
|
throw new Exception("A push stat cannot have a pull action");
|
||||||
|
else
|
||||||
|
PullAction = pullAction;
|
||||||
|
|
||||||
Verbosity = verbosity;
|
Verbosity = verbosity;
|
||||||
Description = description;
|
|
||||||
|
|
||||||
UniqueName = GenUniqueName(Container, Category, ShortName);
|
UniqueName = GenUniqueName(Container, Category, ShortName);
|
||||||
}
|
}
|
||||||
|
@ -361,8 +417,15 @@ namespace OpenSim.Framework.Monitoring
|
||||||
}
|
}
|
||||||
|
|
||||||
public PercentageStat(
|
public PercentageStat(
|
||||||
string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
|
string shortName,
|
||||||
: base(shortName, name, "%", category, container, verbosity, description) {}
|
string name,
|
||||||
|
string description,
|
||||||
|
string category,
|
||||||
|
string container,
|
||||||
|
StatType type,
|
||||||
|
Action<Stat> pullAction,
|
||||||
|
StatVerbosity verbosity)
|
||||||
|
: base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
|
||||||
|
|
||||||
public override string ToConsoleString()
|
public override string ToConsoleString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,8 +38,23 @@ namespace OpenSim.Framework
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class Pool<T>
|
public class Pool<T>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Number of objects in the pool.
|
||||||
|
/// </summary>
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (m_pool)
|
||||||
|
return m_pool.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Stack<T> m_pool;
|
private Stack<T> m_pool;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum pool size. Beyond this, any returned objects are not pooled.
|
||||||
|
/// </summary>
|
||||||
private int m_maxPoolSize;
|
private int m_maxPoolSize;
|
||||||
|
|
||||||
private Func<T> m_createFunction;
|
private Func<T> m_createFunction;
|
||||||
|
|
|
@ -278,7 +278,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ThrottleRates = new ThrottleRates(configSource);
|
ThrottleRates = new ThrottleRates(configSource);
|
||||||
|
|
||||||
if (UsePools)
|
if (UsePools)
|
||||||
|
{
|
||||||
m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
|
m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
|
||||||
|
|
||||||
|
StatsManager.RegisterStat(
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Monitoring;
|
||||||
|
|
||||||
namespace OpenMetaverse
|
namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
|
@ -107,9 +108,25 @@ namespace OpenMetaverse
|
||||||
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
|
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
|
||||||
{
|
{
|
||||||
if (UsePools)
|
if (UsePools)
|
||||||
|
{
|
||||||
m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
|
m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
|
||||||
|
|
||||||
|
StatsManager.RegisterStat(
|
||||||
|
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));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_pool = null;
|
m_pool = null;
|
||||||
|
}
|
||||||
|
|
||||||
m_asyncPacketHandling = asyncPacketHandling;
|
m_asyncPacketHandling = asyncPacketHandling;
|
||||||
|
|
||||||
|
|
|
@ -47,18 +47,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private PercentageStat m_packetsReusedStat = new PercentageStat(
|
private PercentageStat m_packetsReusedStat = new PercentageStat(
|
||||||
"PacketsReused",
|
"PacketsReused",
|
||||||
"Packets reused",
|
"Packets reused",
|
||||||
|
"Number of packets reused out of all requests to the packet pool",
|
||||||
"clientstack",
|
"clientstack",
|
||||||
"packetpool",
|
"packetpool",
|
||||||
StatVerbosity.Debug,
|
StatType.Push,
|
||||||
"Number of packets reused out of all requests to the packet pool");
|
null,
|
||||||
|
StatVerbosity.Debug);
|
||||||
|
|
||||||
private PercentageStat m_blocksReusedStat = new PercentageStat(
|
private PercentageStat m_blocksReusedStat = new PercentageStat(
|
||||||
"BlocksReused",
|
"PacketDataBlocksReused",
|
||||||
"Blocks reused",
|
"Packet data blocks reused",
|
||||||
|
"Number of data blocks reused out of all requests to the packet pool",
|
||||||
"clientstack",
|
"clientstack",
|
||||||
"packetpool",
|
"packetpool",
|
||||||
StatVerbosity.Debug,
|
StatType.Push,
|
||||||
"Number of data blocks reused out of all requests to the packet pool");
|
null,
|
||||||
|
StatVerbosity.Debug);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pool of packets available for reuse.
|
/// Pool of packets available for reuse.
|
||||||
|
@ -88,6 +92,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
StatsManager.RegisterStat(m_packetsReusedStat);
|
StatsManager.RegisterStat(m_packetsReusedStat);
|
||||||
StatsManager.RegisterStat(m_blocksReusedStat);
|
StatsManager.RegisterStat(m_blocksReusedStat);
|
||||||
|
|
||||||
|
StatsManager.RegisterStat(
|
||||||
|
new Stat(
|
||||||
|
"PacketsPoolCount",
|
||||||
|
"Objects within the packet pool",
|
||||||
|
"The number of objects currently stored within the packet pool",
|
||||||
|
"",
|
||||||
|
"clientstack",
|
||||||
|
"packetpool",
|
||||||
|
StatType.Pull,
|
||||||
|
stat => { lock (pool) { stat.Value = pool.Count; } },
|
||||||
|
StatVerbosity.Debug));
|
||||||
|
|
||||||
|
StatsManager.RegisterStat(
|
||||||
|
new Stat(
|
||||||
|
"PacketDataBlocksPoolCount",
|
||||||
|
"Objects within the packet data block pool",
|
||||||
|
"The number of objects currently stored within the packet data block pool",
|
||||||
|
"",
|
||||||
|
"clientstack",
|
||||||
|
"packetpool",
|
||||||
|
StatType.Pull,
|
||||||
|
stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
|
||||||
|
StatVerbosity.Debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -245,11 +245,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
= new Stat(
|
= new Stat(
|
||||||
"SlowFrames",
|
"SlowFrames",
|
||||||
"Slow Frames",
|
"Slow Frames",
|
||||||
|
"Number of frames where frame time has been significantly longer than the desired frame time.",
|
||||||
" frames",
|
" frames",
|
||||||
"scene",
|
"scene",
|
||||||
m_scene.Name,
|
m_scene.Name,
|
||||||
StatVerbosity.Info,
|
StatType.Push,
|
||||||
"Number of frames where frame time has been significantly longer than the desired frame time.");
|
null,
|
||||||
|
StatVerbosity.Info);
|
||||||
|
|
||||||
StatsManager.RegisterStat(SlowFramesStat);
|
StatsManager.RegisterStat(SlowFramesStat);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue