From 4578ff74fec7500902f58fbdee6ce5a6b39601fb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Oct 2012 01:50:05 +0100 Subject: 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. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 14 ++++++++ .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 17 +++++++++ .../Region/ClientStack/Linden/UDP/PacketPool.cs | 40 ++++++++++++++++++---- 3 files changed, 65 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 419de66..bcfd392 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -278,7 +278,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP ThrottleRates = new ThrottleRates(configSource); if (UsePools) + { m_incomingPacketPool = new Pool(() => 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() diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 6e6b3ef..18abfd6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -31,6 +31,7 @@ using System.Net.Sockets; using System.Threading; using log4net; using OpenSim.Framework; +using OpenSim.Framework.Monitoring; namespace OpenMetaverse { @@ -107,9 +108,25 @@ namespace OpenMetaverse public void StartInbound(int recvBufferSize, bool asyncPacketHandling) { if (UsePools) + { m_pool = new Pool(() => 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 + { m_pool = null; + } m_asyncPacketHandling = asyncPacketHandling; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 2a3d14f..9f22fb4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -47,18 +47,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP private PercentageStat m_packetsReusedStat = new PercentageStat( "PacketsReused", "Packets reused", + "Number of packets reused out of all requests to the packet pool", "clientstack", "packetpool", - StatVerbosity.Debug, - "Number of packets reused out of all requests to the packet pool"); + StatType.Push, + null, + StatVerbosity.Debug); private PercentageStat m_blocksReusedStat = new PercentageStat( - "BlocksReused", - "Blocks reused", + "PacketDataBlocksReused", + "Packet data blocks reused", + "Number of data blocks reused out of all requests to the packet pool", "clientstack", "packetpool", - StatVerbosity.Debug, - "Number of data blocks reused out of all requests to the packet pool"); + StatType.Push, + null, + StatVerbosity.Debug); /// /// Pool of packets available for reuse. @@ -88,6 +92,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP { StatsManager.RegisterStat(m_packetsReusedStat); 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)); } /// -- cgit v1.1 From 319ebaca06db3d4a38beff74725d321b7c836157 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Oct 2012 02:44:15 +0100 Subject: Make it possible to turn the base UDP object packet pools on and off whilst running via the "debug lludp pool " console command. For debug purposes. This does not currently apply to the higher LLUDP packetpool. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 103 +++++++++++++++++---- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 66 ++++++++----- 2 files changed, 131 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index bcfd392..14cc863 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -170,6 +170,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Pool m_incomingPacketPool; + private Stat m_incomingPacketPoolStat; + private int m_defaultRTO = 0; private int m_maxRTO = 0; private int m_ackTimeout = 0; @@ -214,6 +216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_circuitManager = circuitManager; int sceneThrottleBps = 0; + bool usePools = false; IConfig config = configSource.Configs["ClientStack.LindenUDP"]; if (config != null) @@ -246,7 +249,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); - UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false); + usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools); } #region BinaryStats @@ -277,22 +280,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_throttle = new TokenBucket(null, sceneThrottleBps); ThrottleRates = new ThrottleRates(configSource); - if (UsePools) - { - m_incomingPacketPool = new Pool(() => 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)); - } + if (usePools) + EnablePools(); } public void Start() @@ -345,6 +334,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP base.StopInbound(); } + protected override bool EnablePools() + { + if (!UsePools) + { + base.EnablePools(); + + m_incomingPacketPool = new Pool(() => 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 false; + } + + protected override bool DisablePools() + { + if (UsePools) + { + base.DisablePools(); + + StatsManager.DeregisterStat(m_incomingPacketPoolStat); + + // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. + + return true; + } + + return false; + } + /// /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. /// @@ -411,6 +444,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP MainConsole.Instance.Commands.AddCommand( "Debug", false, + "debug lludp pool", + "debug lludp pool ", + "Turn object pooling within the lludp component on or off.", + HandlePoolCommand); + + MainConsole.Instance.Commands.AddCommand( + "Debug", + false, "debug lludp status", "debug lludp status", "Return status of LLUDP packet processing.", @@ -451,6 +492,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP StopOutbound(); } + private void HandlePoolCommand(string module, string[] args) + { + if (args.Length != 4) + { + MainConsole.Instance.Output("Usage: debug lludp pool "); + return; + } + + string enabled = args[3]; + + if (enabled == "on") + { + if (EnablePools()) + MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); + } + else if (enabled == "off") + { + if (DisablePools()) + MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); + } + else + { + MainConsole.Instance.Output("Usage: debug lludp pool "); + } + } + private void HandleStatusCommand(string module, string[] args) { MainConsole.Instance.OutputFormat( @@ -458,6 +525,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP MainConsole.Instance.OutputFormat( "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); + + MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off"); } public bool HandlesRegion(Location x) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 18abfd6..85cbb06 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -77,6 +77,8 @@ namespace OpenMetaverse /// If IsRunningOut = false, then any request to send a packet is simply dropped. public bool IsRunningOutbound { get; private set; } + private Stat m_poolCountStat; + /// /// Default constructor /// @@ -107,27 +109,6 @@ namespace OpenMetaverse /// necessary public void StartInbound(int recvBufferSize, bool asyncPacketHandling) { - if (UsePools) - { - m_pool = new Pool(() => 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 - { - m_pool = null; - } - m_asyncPacketHandling = asyncPacketHandling; if (!IsRunningInbound) @@ -197,6 +178,49 @@ namespace OpenMetaverse IsRunningOutbound = false; } + protected virtual bool EnablePools() + { + if (!UsePools) + { + m_pool = new Pool(() => 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; + + return true; + } + + return false; + } + + protected virtual bool DisablePools() + { + if (UsePools) + { + 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. + + return true; + } + + return false; + } + private void AsyncBeginReceive() { UDPPacketBuffer buf; -- cgit v1.1 From c13a99dc5cc82efac5497dab27dcb6b0d9865cea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 25 Oct 2012 03:26:12 +0100 Subject: Fix script error messages not showing up in viewer 3 and associated viewers. Viewer 3 will discard such a message if the chat message owner does not match the avatar. We were filling the ownerID with the primID, so this never matched, hence viewer 3 did not see any script error messages. This commit fills the ownerID in with the prim ownerID so the script owner will receive script error messages. This does not affect viewer 1 and associated viewers which continue to process script errors as normal. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7427c59..8e5a6d2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -817,8 +817,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(mov, ThrottleOutPacketType.Unknown); } - public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, - UUID fromAgentID, byte source, byte audible) + public void SendChatMessage( + string message, byte type, Vector3 fromPos, string fromName, + UUID fromAgentID, UUID ownerID, byte source, byte audible) { ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); reply.ChatData.Audible = audible; @@ -827,7 +828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP reply.ChatData.SourceType = source; reply.ChatData.Position = fromPos; reply.ChatData.FromName = Util.StringToBytes256(fromName); - reply.ChatData.OwnerID = fromAgentID; + reply.ChatData.OwnerID = ownerID; reply.ChatData.SourceID = fromAgentID; OutPacket(reply, ThrottleOutPacketType.Task); -- cgit v1.1 From 4ba48151b232716ebb473bc320793a9610a96e5b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Oct 2012 00:39:45 +0000 Subject: Handle UUIDGroupName and ObjectGroup viewer UDP requests asynchronously rather than synchronously. This is to avoid the entire scene loop being held up when the group service is slow to respond. There's no obvious reason for these queries to be sync rather than async. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8e5a6d2..7382e09 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5219,8 +5219,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); - AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest, false); - AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest, false); + AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); + AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); -- cgit v1.1 From aeeaa3a0a9b965dfe5d1111b178234c94de9ba9d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 14 Nov 2012 11:09:43 -0800 Subject: Added AssemblyInfos to every dll in the OpenSim.Region namespace. --- .../Linden/UDP/Properties/AssemblyInfo.cs | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..af2f6f8 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenUDP")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9d3dbc6b-9d85-483b-af48-c1dfc261b7ac")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] -- cgit v1.1 From 2c36106675ad984ba5af674cbb970b17ffa320bb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Nov 2012 01:14:18 +0000 Subject: 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. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 103 ++++++++++++++++++--- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 31 ++----- 2 files changed, 96 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 14cc863..f8391d7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -70,6 +70,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void AddScene(IScene 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) @@ -170,6 +182,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Pool m_incomingPacketPool; + /// + /// Stat for number of packets in the main pool awaiting use. + /// + private Stat m_poolCountStat; + + /// + /// Stat for number of packets in the inbound packet pool awaiting use. + /// private Stat m_incomingPacketPoolStat; private int m_defaultRTO = 0; @@ -342,20 +362,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_incomingPacketPool = new Pool(() => 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; } @@ -379,6 +385,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// + /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene + /// stats. + /// + 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); + } + + /// + /// Disables pool stats. + /// + private void DisablePoolStats() + { + StatsManager.DeregisterStat(m_poolCountStat); + m_poolCountStat = null; + + StatsManager.DeregisterStat(m_incomingPacketPoolStat); + m_incomingPacketPoolStat = null; + } + + /// /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. /// /// @@ -416,6 +469,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_scene = (Scene)scene; 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( "Debug", @@ -505,12 +563,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (enabled == "on") { if (EnablePools()) + { + EnablePoolStats(); MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); + } } else if (enabled == "off") { if (DisablePools()) + { + DisablePoolStats(); MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); + } } else { @@ -1556,6 +1620,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int npacksSent = 0; private int npackNotSent = 0; + /// + /// Number of inbound packets processed since startup. + /// + public long IncomingPacketsProcessed { get; private set; } + private void MonitoredClientOutgoingPacketHandler(IClientAPI client) { nticks++; @@ -1615,7 +1684,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP npacksSent++; } else + { npackNotSent++; + } watch2.Stop(); avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); @@ -1623,7 +1694,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else + { m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); + } } } catch (Exception ex) @@ -1687,6 +1760,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", packet.Type, client.Name, m_scene.RegionInfo.RegionName); } + + IncomingPacketsProcessed++; } protected void LogoutHandler(IClientAPI client) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 85cbb06..808d177 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -61,14 +61,14 @@ namespace OpenMetaverse private bool m_asyncPacketHandling; /// - /// Pool to use for handling data. May be null if UsePools = false; + /// Are we to use object pool(s) to reduce memory churn when receiving data? /// - protected OpenSim.Framework.Pool m_pool; + public bool UsePools { get; protected set; } /// - /// Are we to use object pool(s) to reduce memory churn when receiving data? + /// Pool to use for handling data. May be null if UsePools = false; /// - public bool UsePools { get; protected set; } + protected OpenSim.Framework.Pool Pool { get; private set; } /// Returns true if the server is currently listening for inbound packets, otherwise false public bool IsRunningInbound { get; private set; } @@ -77,8 +77,6 @@ namespace OpenMetaverse /// If IsRunningOut = false, then any request to send a packet is simply dropped. public bool IsRunningOutbound { get; private set; } - private Stat m_poolCountStat; - /// /// Default constructor /// @@ -182,21 +180,7 @@ namespace OpenMetaverse { if (!UsePools) { - m_pool = new Pool(() => 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); + Pool = new Pool(() => new UDPPacketBuffer(), 500); UsePools = true; @@ -211,7 +195,6 @@ namespace OpenMetaverse if (UsePools) { 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. @@ -226,7 +209,7 @@ namespace OpenMetaverse UDPPacketBuffer buf; if (UsePools) - buf = m_pool.GetObject(); + buf = Pool.GetObject(); else buf = new UDPPacketBuffer(); @@ -309,7 +292,7 @@ namespace OpenMetaverse finally { if (UsePools) - m_pool.ReturnObject(buffer); + Pool.ReturnObject(buffer); // Synchronous mode waits until the packet callback completes // before starting the receive to fetch another packet -- cgit v1.1 From 038528dc80e0fe03956d61872ba30a887b2890a1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Nov 2012 02:02:59 +0000 Subject: Make PacketPool class stats pull stats instead of push stats so they can be lifted up into LLUDPServer and be distiguished by scene name --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 54 ++++++++++ .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 2 +- .../Region/ClientStack/Linden/UDP/PacketPool.cs | 114 ++++++++++----------- 3 files changed, 107 insertions(+), 63 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index f8391d7..fcc69c0 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -469,6 +469,60 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_scene = (Scene)scene; m_location = new Location(m_scene.RegionInfo.RegionHandle); + + // XXX: These stats are also pool stats but we register them separately since they are currently not + // turned on and off by EnablePools()/DisablePools() + StatsManager.RegisterStat( + new PercentageStat( + "PacketsReused", + "Packets reused", + "Number of packets reused out of all requests to the packet pool", + "clientstack", + m_scene.Name, + StatType.Pull, + stat => + { PercentageStat pstat = (PercentageStat)stat; + pstat.Consequent = PacketPool.Instance.PacketsRequested; + pstat.Antecedent = PacketPool.Instance.PacketsReused; }, + StatVerbosity.Debug)); + + StatsManager.RegisterStat( + new PercentageStat( + "PacketDataBlocksReused", + "Packet data blocks reused", + "Number of data blocks reused out of all requests to the packet pool", + "clientstack", + m_scene.Name, + StatType.Pull, + stat => + { PercentageStat pstat = (PercentageStat)stat; + pstat.Consequent = PacketPool.Instance.BlocksRequested; + pstat.Antecedent = PacketPool.Instance.BlocksReused; }, + StatVerbosity.Debug)); + + StatsManager.RegisterStat( + new Stat( + "PacketsPoolCount", + "Objects within the packet pool", + "The number of objects currently stored within the packet pool", + "", + "clientstack", + m_scene.Name, + StatType.Pull, + stat => stat.Value = PacketPool.Instance.PacketsPooled, + 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", + m_scene.Name, + StatType.Pull, + stat => stat.Value = PacketPool.Instance.BlocksPooled, + StatVerbosity.Debug)); // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by // scene name diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 808d177..3f7ca2b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -334,4 +334,4 @@ namespace OpenMetaverse catch (ObjectDisposedException) { } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 9f22fb4..1fdc410 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -41,29 +41,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private static readonly PacketPool instance = new PacketPool(); - private bool packetPoolEnabled = true; - private bool dataBlockPoolEnabled = true; - - private PercentageStat m_packetsReusedStat = new PercentageStat( - "PacketsReused", - "Packets reused", - "Number of packets reused out of all requests to the packet pool", - "clientstack", - "packetpool", - StatType.Push, - null, - StatVerbosity.Debug); - - private PercentageStat m_blocksReusedStat = new PercentageStat( - "PacketDataBlocksReused", - "Packet data blocks reused", - "Number of data blocks reused out of all requests to the packet pool", - "clientstack", - "packetpool", - StatType.Push, - null, - StatVerbosity.Debug); - /// /// Pool of packets available for reuse. /// @@ -76,46 +53,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP get { return instance; } } - public bool RecyclePackets + public bool RecyclePackets { get; set; } + + public bool RecycleDataBlocks { get; set; } + + /// + /// The number of packets pooled + /// + public int PacketsPooled { - set { packetPoolEnabled = value; } - get { return packetPoolEnabled; } + get + { + lock (pool) + return pool.Count; + } } - public bool RecycleDataBlocks + /// + /// The number of blocks pooled. + /// + public int BlocksPooled { - set { dataBlockPoolEnabled = value; } - get { return dataBlockPoolEnabled; } + get + { + lock (DataBlocks) + return DataBlocks.Count; + } } + /// + /// Number of packets requested. + /// + public long PacketsRequested { get; private set; } + + /// + /// Number of packets reused. + /// + public long PacketsReused { get; private set; } + + /// + /// Number of packet blocks requested. + /// + public long BlocksRequested { get; private set; } + + /// + /// Number of packet blocks reused. + /// + public long BlocksReused { get; private set; } + private PacketPool() { - StatsManager.RegisterStat(m_packetsReusedStat); - 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)); + // defaults + RecyclePackets = true; + RecycleDataBlocks = true; } /// @@ -125,11 +115,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Guaranteed to always return a packet, whether from the pool or newly constructed. public Packet GetPacket(PacketType type) { - m_packetsReusedStat.Consequent++; + PacketsRequested++; Packet packet; - if (!packetPoolEnabled) + if (!RecyclePackets) return Packet.BuildPacket(type); lock (pool) @@ -146,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); // Recycle old packages - m_packetsReusedStat.Antecedent++; + PacketsReused++; packet = pool[type].Pop(); } @@ -215,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public void ReturnPacket(Packet packet) { - if (dataBlockPoolEnabled) + if (RecycleDataBlocks) { switch (packet.Type) { @@ -239,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - if (packetPoolEnabled) + if (RecyclePackets) { switch (packet.Type) { @@ -277,7 +267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (DataBlocks) { - m_blocksReusedStat.Consequent++; + BlocksRequested++; Stack s; @@ -285,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (s.Count > 0) { - m_blocksReusedStat.Antecedent++; + BlocksReused++; return (T)s.Pop(); } } -- cgit v1.1 From df4da51f04ea2900032a6bd2749039bee5338f54 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Nov 2012 03:04:46 +0000 Subject: Following on from 4f982596, launch map name requests on an async thread from LLClientView directly. This releases the inbound packet handling thread marginally quicker and is more consistent with the other async packet handling --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7382e09..c93dbfc 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5322,7 +5322,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest, false); AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); - AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest, false); + AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest); AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); -- cgit v1.1 From 57273ef7b24c5ae466ebb6051a5c614a3c07fe2d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Nov 2012 03:07:45 +0000 Subject: Do HandleMapLayerRequest on its own thread rather than on the main inbound udp packet handling thread. There's no obvious race condition reason for doing this on the main packet handling thread. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c93dbfc..92a630f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5320,7 +5320,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory); AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); - AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest, false); + AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest); AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest); AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); -- cgit v1.1 From daf03bfb567a7a93a9259945386325fd924f8bd1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Nov 2012 03:09:20 +0000 Subject: Handle Map block requests on a separate thread rather than the main packet handling thread. This prevents a slow grid information network call from holding up the main packet handling thread. There's no obvious race condition reason for not doing this asynchronously. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 92a630f..4fd81fa 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5321,7 +5321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest); - AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); + AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest); AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest); AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); -- cgit v1.1 From cd088757e96217defc9a2b0bf323747615c3255e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Nov 2012 04:36:22 +0000 Subject: Add a first draft mechanism for the IncomingPacketsProcessedStat to show the delta over time. The chief motivation for this is to be able to tell whether there's any impact on incoming packet processing from enabling extra packet pooling. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index fcc69c0..a7628d2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -80,6 +80,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP "clientstack", scene.Name, StatType.Pull, + MeasuresOfInterest.AverageChangeOverTime, stat => stat.Value = m_udpServer.IncomingPacketsProcessed, StatVerbosity.Debug)); } -- cgit v1.1 From 22d4c52ffc374e167cb674e0e20815615d8a6927 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 03:15:24 +0000 Subject: Consistenly make NUnit test cases inherit from OpenSimTestCase which automatically turns off any logging enabled between tests --- OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 5fcf376..7d9f581 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs @@ -43,7 +43,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.ClientStack.LindenUDP.Tests { [TestFixture] - public class LLImageManagerTests + public class LLImageManagerTests : OpenSimTestCase { private AssetBase m_testImageAsset; private Scene scene; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs index 0f88ec6..5f73a94 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs @@ -39,7 +39,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests /// Tests for the LL packet handler /// [TestFixture] - public class PacketHandlerTests + public class PacketHandlerTests : OpenSimTestCase { // [Test] // /// -- cgit v1.1