diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 9dc9e0d7ac..d8ca343293 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -82,6 +82,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Any level above 0 will turn on logging.
public int DebugDataOutLevel { get; set; }
+ ///
+ /// Controls whether information is logged about each outbound packet immediately before it is sent. For debug purposes.
+ ///
+ /// Any level above 0 will turn on logging.
+ public int ThrottleDebugLevel
+ {
+ get
+ {
+ return m_throttleDebugLevel;
+ }
+
+ set
+ {
+ m_throttleDebugLevel = value;
+ m_throttleClient.DebugLevel = m_throttleDebugLevel;
+ m_throttleCategory.DebugLevel = m_throttleDebugLevel;
+ foreach (TokenBucket tb in m_throttleCategories)
+ tb.DebugLevel = m_throttleDebugLevel;
+ }
+ }
+ private int m_throttleDebugLevel;
+
/// Fired when updated networking stats are produced for this client
public event PacketStats OnPacketStats;
/// Fired when the queue for a packet category is empty. This event can be
@@ -207,9 +229,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_maxRTO = maxRTO;
// Create a token bucket throttle for this client that has the scene token bucket as a parent
- m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
+ m_throttleClient
+ = new AdaptiveTokenBucket(
+ string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name),
+ parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
+
// Create a token bucket throttle for the total category with the client bucket as a throttle
- m_throttleCategory = new TokenBucket(m_throttleClient, 0);
+ m_throttleCategory
+ = new TokenBucket(
+ string.Format("total throttle for {0} in {1}", AgentID, server.Scene.Name),
+ m_throttleClient, 0);
+
// Create an array of token buckets for this clients different throttle categories
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
@@ -221,8 +251,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Initialize the packet outboxes, where packets sit while they are waiting for tokens
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue();
+
// Initialize the token buckets that control the throttling for each category
- m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
+ m_throttleCategories[i]
+ = new TokenBucket(
+ string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name),
+ m_throttleCategory, rates.GetRate(type));
}
// Default the retransmission timeout to one second
@@ -371,8 +405,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
texture = (int)((1 - m_cannibalrate) * texture);
//int total = resend + land + wind + cloud + task + texture + asset;
- //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}",
- // AgentID, resend, land, wind, cloud, task, texture, asset, total);
+
+ if (ThrottleDebugLevel > 0)
+ m_log.DebugFormat(
+ "[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}",
+ AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset);
// Update the token buckets with new throttle values
TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index a90ea6cebe..0b1c7fe337 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -434,7 +434,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion BinaryStats
- m_throttle = new TokenBucket(null, sceneThrottleBps);
+ // FIXME: Can't add info here because don't know scene yet.
+// m_throttle
+// = new TokenBucket(
+// string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps);
+
+ m_throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps);
+
ThrottleRates = new ThrottleRates(configSource);
if (usePools)
@@ -755,6 +761,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"Return status of LLUDP packet processing.",
HandleStatusCommand);
+ MainConsole.Instance.Commands.AddCommand(
+ "Debug",
+ false,
+ "debug lludp throttle log",
+ "debug lludp throttle log ",
+ "Change debug logging level for throttles.",
+ "If level >= 0 then throttle debug logging is performed.\n"
+ + "If level <= 0 then no throttle debug logging is performed.",
+ HandleThrottleCommand);
+
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
@@ -795,6 +811,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
});
}
+ private void HandleThrottleCommand(string module, string[] args)
+ {
+ if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
+ return;
+
+ if (args.Length != 7)
+ {
+ MainConsole.Instance.OutputFormat("Usage: debug lludp throttle log ");
+ return;
+ }
+
+ int level;
+ if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
+ return;
+
+ string firstName = args[5];
+ string lastName = args[6];
+
+ Scene.ForEachScenePresence(sp =>
+ {
+ if (sp.Firstname == firstName && sp.Lastname == lastName)
+ {
+ MainConsole.Instance.OutputFormat(
+ "Throttle log level for {0} ({1}) set to {2} in {3}",
+ sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name);
+
+ ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
+ }
+ });
+ }
+
private void HandlePacketCommand(string module, string[] args)
{
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index 0d4f54951e..658d9bbd3c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -43,8 +43,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Int32 m_counter = 0;
-
-// private Int32 m_identifier;
+
+ private LLUDPClient m_client;
+
+ public string Identifier { get; private set; }
+
+ public int DebugLevel { get; set; }
///
/// Number of ticks (ms) per quantum, drip rate and max burst
@@ -165,16 +169,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
/// Default constructor
///
+ /// Identifier for this token bucket
/// Parent bucket if this is a child bucket, or
/// null if this is a root bucket
- /// Maximum size of the bucket in bytes, or
- /// zero if this bucket has no maximum capacity
/// Rate that the bucket fills, in bytes per
/// second. If zero, the bucket always remains full
- public TokenBucket(TokenBucket parent, Int64 dripRate)
+ public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate)
{
-// m_identifier = m_counter++;
- m_counter++;
+ Identifier = identifier;
Parent = parent;
RequestedDripRate = dripRate;
@@ -301,7 +303,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// with no drip rate...
if (DripRate == 0)
{
- m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0");
+ m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0 for {0}", Identifier);
return;
}
@@ -321,7 +323,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public class AdaptiveTokenBucket : TokenBucket
{
-// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
///
/// The minimum rate for flow control. Minimum drip rate is one
@@ -360,13 +362,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//
//
//
- public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate)
+ public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 maxDripRate, bool enabled)
+ : base(identifier, parent, maxDripRate)
{
Enabled = enabled;
if (Enabled)
{
- // m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled");
+// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled");
MaxDripRate = maxDripRate;
AdjustedDripRate = m_minimumFlow;
}
@@ -377,9 +380,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//
public void ExpirePackets(Int32 count)
{
- // m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count);
if (Enabled)
+ {
+ if (DebugLevel > 0)
+ m_log.WarnFormat(
+ "[ADAPTIVEBUCKET] drop {0} by {1} expired packets for {2}",
+ AdjustedDripRate, count, Identifier);
+
AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
+ }
}
//