diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 415a22efa6..aa103018df 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -447,7 +447,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// = new TokenBucket(
// string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps);
- Throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps, sceneThrottleBps);
+ Throttle = new TokenBucket("server throttle bucket", null, 0, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
index 60b93ac11e..e0398d58fb 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
@@ -512,7 +512,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
return;
- m_udpServer.Throttle.RequestedDripRate = newValue * 1000 / 8;
+ m_udpServer.Throttle.MaxDripRate = newValue * 1000 / 8;
}
else if (param == "max-new-client-throttle")
{
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
index 0d39c1d393..912c9940f5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
@@ -57,51 +57,71 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
[Test]
public void TestSetRequestDripRate()
{
+ TestHelpers.InMethod();
+
TokenBucket tb = new TokenBucket("tb", null, 5000, 0);
- AssertRates(tb, 5000, 5000, 5000, 0);
+ AssertRates(tb, 5000, 0, 5000, 0);
tb.RequestedDripRate = 4000;
- AssertRates(tb, 4000, 4000, 4000, 0);
+ AssertRates(tb, 4000, 0, 4000, 0);
tb.RequestedDripRate = 6000;
- AssertRates(tb, 6000, 6000, 6000, 0);
+ AssertRates(tb, 6000, 0, 6000, 0);
}
[Test]
public void TestSetRequestDripRateWithMax()
{
+ TestHelpers.InMethod();
+
TokenBucket tb = new TokenBucket("tb", null, 5000, 10000);
- AssertRates(tb, 5000, 5000, 5000, 10000);
+ AssertRates(tb, 5000, 0, 5000, 10000);
tb.RequestedDripRate = 4000;
- AssertRates(tb, 4000, 4000, 4000, 10000);
+ AssertRates(tb, 4000, 0, 4000, 10000);
tb.RequestedDripRate = 6000;
- AssertRates(tb, 6000, 6000, 6000, 10000);
+ AssertRates(tb, 6000, 0, 6000, 10000);
tb.RequestedDripRate = 12000;
- AssertRates(tb, 10000, 10000, 10000, 10000);
+ AssertRates(tb, 10000, 0, 10000, 10000);
}
[Test]
public void TestSetRequestDripRateWithChildren()
{
+ TestHelpers.InMethod();
+
TokenBucket tbParent = new TokenBucket("tbParent", null, 0, 0);
TokenBucket tbChild1 = new TokenBucket("tbChild1", tbParent, 3000, 0);
TokenBucket tbChild2 = new TokenBucket("tbChild2", tbParent, 5000, 0);
AssertRates(tbParent, 8000, 8000, 8000, 0);
- AssertRates(tbChild1, 3000, 3000, 3000, 0);
- AssertRates(tbChild2, 5000, 5000, 5000, 0);
+ AssertRates(tbChild1, 3000, 0, 3000, 0);
+ AssertRates(tbChild2, 5000, 0, 5000, 0);
+
+ // Test: Setting a parent request greater than total children requests.
+ tbParent.RequestedDripRate = 10000;
+
+ AssertRates(tbParent, 10000, 8000, 8000, 0);
+ AssertRates(tbChild1, 3000, 0, 3000, 0);
+ AssertRates(tbChild2, 5000, 0, 5000, 0);
+
+ // Test: Setting a parent request lower than total children requests.
+ tbParent.RequestedDripRate = 6000;
+
+ AssertRates(tbParent, 6000, 8000, 6000, 0);
+ AssertRates(tbChild1, 3000, 0, 6000 / 8 * 3, 0);
+ AssertRates(tbChild2, 5000, 0, 6000 / 8 * 5, 0);
}
private void AssertRates(
TokenBucket tb, double requestedDripRate, double totalDripRequest, double dripRate, double maxDripRate)
{
- Assert.AreEqual((int)requestedDripRate, tb.RequestedDripRate);
- Assert.AreEqual((int)totalDripRequest, tb.TotalDripRequest);
- Assert.AreEqual((int)dripRate, tb.DripRate);
- Assert.AreEqual((int)maxDripRate, tb.MaxDripRate);
+ Assert.AreEqual((int)requestedDripRate, tb.RequestedDripRate, "Requested drip rate");
+ Assert.AreEqual((int)totalDripRequest, tb.TotalDripRequest, "Total drip request");
+ Assert.AreEqual((int)dripRate, tb.DripRate, "Drip rate");
+ Assert.AreEqual((int)maxDripRate, tb.MaxDripRate, "Max drip rate");
}
[Test]
@@ -360,16 +380,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
- Assert.AreEqual((int)resendBytes, ci.resendThrottle);
- Assert.AreEqual((int)landBytes, ci.landThrottle);
- Assert.AreEqual((int)windBytes, ci.windThrottle);
- Assert.AreEqual((int)cloudBytes, ci.cloudThrottle);
- Assert.AreEqual((int)taskBytes, ci.taskThrottle);
- Assert.AreEqual((int)textureBytes, ci.textureThrottle);
- Assert.AreEqual((int)assetBytes, ci.assetThrottle);
- Assert.AreEqual((int)totalBytes, ci.totalThrottle);
- Assert.AreEqual((int)targetBytes, ci.targetThrottle);
- Assert.AreEqual((int)maxBytes, ci.maxThrottle);
+ Assert.AreEqual((int)resendBytes, ci.resendThrottle, "Resend");
+ Assert.AreEqual((int)landBytes, ci.landThrottle, "Land");
+ Assert.AreEqual((int)windBytes, ci.windThrottle, "Wind");
+ Assert.AreEqual((int)cloudBytes, ci.cloudThrottle, "Cloud");
+ Assert.AreEqual((int)taskBytes, ci.taskThrottle, "Task");
+ Assert.AreEqual((int)textureBytes, ci.textureThrottle, "Texture");
+ Assert.AreEqual((int)assetBytes, ci.assetThrottle, "Asset");
+ Assert.AreEqual((int)totalBytes, ci.totalThrottle, "Total");
+ Assert.AreEqual((int)targetBytes, ci.targetThrottle, "Target");
+ Assert.AreEqual((int)maxBytes, ci.maxThrottle, "Max");
}
private void SetThrottles(
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index e0633d338f..ab8d2685d5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -110,14 +110,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
///
- /// The speed limit of this bucket in bytes per second. This is the
- /// number of tokens that are added to the bucket per quantum
+ /// The requested drip rate for this particular bucket.
///
///
- /// RequestedDripRate can never be above MaxDripRate.
- /// Tokens are added to the bucket any time
+ /// 0 then TotalDripRequest is used instead.
+ /// Can never be above MaxDripRate.
+ /// Tokens are added to the bucket at any time
/// is called, at the granularity of
- /// the system tick interval (typically around 15-22ms)
+ /// the system tick interval (typically around 15-22ms)
+ /// FIXME: It is extremely confusing to be able to set a RequestedDripRate of 0 and then receive a positive
+ /// number on get if TotalDripRequest is sent. This also stops us being able to retrieve the fact that
+ /// RequestedDripRate is set to 0. Really, this should always return m_dripRate and then we can get
+ /// (m_dripRate == 0 ? TotalDripRequest : m_dripRate) on some other properties.
+ ///
protected Int64 m_dripRate;
public virtual Int64 RequestedDripRate
{
@@ -131,7 +136,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else
m_dripRate = value;
- TotalDripRequest = m_dripRate;
m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst);
if (Parent != null)
@@ -142,15 +146,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
/// Gets the drip rate.
///
- /// DripRate can never be above max.
+ ///
+ /// DripRate can never be above max drip rate or below min drip rate.
+ /// If we are a child bucket then the drip rate return is modifed by the total load on the capacity of the
+ /// parent bucket.
+ ///
public virtual Int64 DripRate
{
get
{
+ double rate;
+
+ // FIXME: This doesn't properly work if we have a parent and children and a requested drip rate set
+ // on ourselves which is not equal to the child drip rates.
if (Parent == null)
- return Math.Min(RequestedDripRate, TotalDripRequest);
-
- double rate = (double)RequestedDripRate * Parent.DripRateModifier();
+ {
+ if (TotalDripRequest > 0)
+ rate = Math.Min(RequestedDripRate, TotalDripRequest);
+ else
+ rate = RequestedDripRate;
+ }
+ else
+ {
+ rate = (double)RequestedDripRate * Parent.DripRateModifier();
+ }
+
if (rate < m_minimumDripRate)
rate = m_minimumDripRate;
else if (MaxDripRate > 0 && rate > MaxDripRate)
@@ -163,18 +183,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//
// The maximum rate for flow control. Drip rate can never be greater than this.
//
-// protected Int64 m_maxDripRate;
-// public Int64 MaxDripRate
-// {
-// get { return m_maxDripRate; }
-// //get { return (m_maxDripRate == 0 ? TotalDripRequest : m_maxDripRate); }
-// set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value, m_minimumFlow)); }
-// }
public Int64 MaxDripRate { get; set; }
///
- /// The current total of the requested maximum burst rates of
- /// this bucket's children buckets.
+ /// The current total of the requested maximum burst rates of children buckets.
///
public Int64 TotalDripRequest { get; protected set; }
@@ -197,8 +209,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Parent = parent;
RequestedDripRate = dripRate;
MaxDripRate = maxDripRate;
- // TotalDripRequest = dripRate; // this will be overwritten when a child node registers
- // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
m_lastDrip = Util.EnvironmentTickCount();
}
@@ -243,7 +253,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_children)
{
m_children[child] = request;
- // TotalDripRequest = m_children.Values.Sum();
TotalDripRequest = 0;
foreach (KeyValuePair cref in m_children)
@@ -255,12 +264,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
Int64 effectiveDripRate;
- if (MaxDripRate > 0)
- effectiveDripRate = Math.Min(MaxDripRate, TotalDripRequest);
+ if (RequestedDripRate > 0)
+ effectiveDripRate = Math.Min(RequestedDripRate, TotalDripRequest);
else
effectiveDripRate = TotalDripRequest;
- //Parent.RegisterRequest(this, Math.Min(RequestedDripRate, TotalDripRequest));
Parent.RegisterRequest(this, effectiveDripRate);
}
}
@@ -274,7 +282,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_children)
{
m_children.Remove(child);
- // m_totalDripRequest = m_children.Values.Sum();
TotalDripRequest = 0;
foreach (KeyValuePair cref in m_children)
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index f6772a5f8a..08d0fbf5bb 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -490,7 +490,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
"{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
"Max",
"Target",
- "Total",
+ "Actual",
"Resend",
"Land",
"Wind",
@@ -546,7 +546,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
report.AppendFormat(
"{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-",
- llUdpClient.FlowThrottle.AdaptiveEnabled ? ((ci.targetThrottle * 8) / 1000).ToString() : "-",
+ llUdpClient.FlowThrottle.AdaptiveEnabled
+ ? ((ci.targetThrottle * 8) / 1000).ToString()
+ : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(),
(ci.totalThrottle * 8) / 1000,
(ci.resendThrottle * 8) / 1000,
(ci.landThrottle * 8) / 1000,