diff options
author | Justin Clark-Casey (justincc) | 2014-10-25 02:09:37 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2014-11-25 23:22:20 +0000 |
commit | b2e377f168967f7cedb32f077ee54b9f92439205 (patch) | |
tree | e6904f3c5a57a0334dd59c4164826c6dda0e1f69 | |
parent | Add request drip rate to assertions for token bucket regression tests (diff) | |
download | opensim-SC-b2e377f168967f7cedb32f077ee54b9f92439205.zip opensim-SC-b2e377f168967f7cedb32f077ee54b9f92439205.tar.gz opensim-SC-b2e377f168967f7cedb32f077ee54b9f92439205.tar.bz2 opensim-SC-b2e377f168967f7cedb32f077ee54b9f92439205.tar.xz |
Fix setting of max scene throttle so that setting it restricts the child client throttles properly.
In "show throttles", also renames 'total' column to 'actual' to reflect that it is not necessarily the throttles requested for/by the client.
Also fills out 'target' in non-adapative mode to the actual throttle requested for/by the client.
5 files changed, 82 insertions, 53 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 415a22e..aa10301 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 | |||
447 | // = new TokenBucket( | 447 | // = new TokenBucket( |
448 | // string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps); | 448 | // string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps); |
449 | 449 | ||
450 | Throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps, sceneThrottleBps); | 450 | Throttle = new TokenBucket("server throttle bucket", null, 0, sceneThrottleBps); |
451 | 451 | ||
452 | ThrottleRates = new ThrottleRates(configSource); | 452 | ThrottleRates = new ThrottleRates(configSource); |
453 | 453 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs index 60b93ac..e0398d5 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 | |||
512 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue)) | 512 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue)) |
513 | return; | 513 | return; |
514 | 514 | ||
515 | m_udpServer.Throttle.RequestedDripRate = newValue * 1000 / 8; | 515 | m_udpServer.Throttle.MaxDripRate = newValue * 1000 / 8; |
516 | } | 516 | } |
517 | else if (param == "max-new-client-throttle") | 517 | else if (param == "max-new-client-throttle") |
518 | { | 518 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs index 0d39c1d..912c994 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 | |||
57 | [Test] | 57 | [Test] |
58 | public void TestSetRequestDripRate() | 58 | public void TestSetRequestDripRate() |
59 | { | 59 | { |
60 | TestHelpers.InMethod(); | ||
61 | |||
60 | TokenBucket tb = new TokenBucket("tb", null, 5000, 0); | 62 | TokenBucket tb = new TokenBucket("tb", null, 5000, 0); |
61 | AssertRates(tb, 5000, 5000, 5000, 0); | 63 | AssertRates(tb, 5000, 0, 5000, 0); |
62 | 64 | ||
63 | tb.RequestedDripRate = 4000; | 65 | tb.RequestedDripRate = 4000; |
64 | AssertRates(tb, 4000, 4000, 4000, 0); | 66 | AssertRates(tb, 4000, 0, 4000, 0); |
65 | 67 | ||
66 | tb.RequestedDripRate = 6000; | 68 | tb.RequestedDripRate = 6000; |
67 | AssertRates(tb, 6000, 6000, 6000, 0); | 69 | AssertRates(tb, 6000, 0, 6000, 0); |
68 | } | 70 | } |
69 | 71 | ||
70 | [Test] | 72 | [Test] |
71 | public void TestSetRequestDripRateWithMax() | 73 | public void TestSetRequestDripRateWithMax() |
72 | { | 74 | { |
75 | TestHelpers.InMethod(); | ||
76 | |||
73 | TokenBucket tb = new TokenBucket("tb", null, 5000, 10000); | 77 | TokenBucket tb = new TokenBucket("tb", null, 5000, 10000); |
74 | AssertRates(tb, 5000, 5000, 5000, 10000); | 78 | AssertRates(tb, 5000, 0, 5000, 10000); |
75 | 79 | ||
76 | tb.RequestedDripRate = 4000; | 80 | tb.RequestedDripRate = 4000; |
77 | AssertRates(tb, 4000, 4000, 4000, 10000); | 81 | AssertRates(tb, 4000, 0, 4000, 10000); |
78 | 82 | ||
79 | tb.RequestedDripRate = 6000; | 83 | tb.RequestedDripRate = 6000; |
80 | AssertRates(tb, 6000, 6000, 6000, 10000); | 84 | AssertRates(tb, 6000, 0, 6000, 10000); |
81 | 85 | ||
82 | tb.RequestedDripRate = 12000; | 86 | tb.RequestedDripRate = 12000; |
83 | AssertRates(tb, 10000, 10000, 10000, 10000); | 87 | AssertRates(tb, 10000, 0, 10000, 10000); |
84 | } | 88 | } |
85 | 89 | ||
86 | [Test] | 90 | [Test] |
87 | public void TestSetRequestDripRateWithChildren() | 91 | public void TestSetRequestDripRateWithChildren() |
88 | { | 92 | { |
93 | TestHelpers.InMethod(); | ||
94 | |||
89 | TokenBucket tbParent = new TokenBucket("tbParent", null, 0, 0); | 95 | TokenBucket tbParent = new TokenBucket("tbParent", null, 0, 0); |
90 | TokenBucket tbChild1 = new TokenBucket("tbChild1", tbParent, 3000, 0); | 96 | TokenBucket tbChild1 = new TokenBucket("tbChild1", tbParent, 3000, 0); |
91 | TokenBucket tbChild2 = new TokenBucket("tbChild2", tbParent, 5000, 0); | 97 | TokenBucket tbChild2 = new TokenBucket("tbChild2", tbParent, 5000, 0); |
92 | 98 | ||
93 | AssertRates(tbParent, 8000, 8000, 8000, 0); | 99 | AssertRates(tbParent, 8000, 8000, 8000, 0); |
94 | AssertRates(tbChild1, 3000, 3000, 3000, 0); | 100 | AssertRates(tbChild1, 3000, 0, 3000, 0); |
95 | AssertRates(tbChild2, 5000, 5000, 5000, 0); | 101 | AssertRates(tbChild2, 5000, 0, 5000, 0); |
102 | |||
103 | // Test: Setting a parent request greater than total children requests. | ||
104 | tbParent.RequestedDripRate = 10000; | ||
105 | |||
106 | AssertRates(tbParent, 10000, 8000, 8000, 0); | ||
107 | AssertRates(tbChild1, 3000, 0, 3000, 0); | ||
108 | AssertRates(tbChild2, 5000, 0, 5000, 0); | ||
109 | |||
110 | // Test: Setting a parent request lower than total children requests. | ||
111 | tbParent.RequestedDripRate = 6000; | ||
112 | |||
113 | AssertRates(tbParent, 6000, 8000, 6000, 0); | ||
114 | AssertRates(tbChild1, 3000, 0, 6000 / 8 * 3, 0); | ||
115 | AssertRates(tbChild2, 5000, 0, 6000 / 8 * 5, 0); | ||
96 | } | 116 | } |
97 | 117 | ||
98 | private void AssertRates( | 118 | private void AssertRates( |
99 | TokenBucket tb, double requestedDripRate, double totalDripRequest, double dripRate, double maxDripRate) | 119 | TokenBucket tb, double requestedDripRate, double totalDripRequest, double dripRate, double maxDripRate) |
100 | { | 120 | { |
101 | Assert.AreEqual((int)requestedDripRate, tb.RequestedDripRate); | 121 | Assert.AreEqual((int)requestedDripRate, tb.RequestedDripRate, "Requested drip rate"); |
102 | Assert.AreEqual((int)totalDripRequest, tb.TotalDripRequest); | 122 | Assert.AreEqual((int)totalDripRequest, tb.TotalDripRequest, "Total drip request"); |
103 | Assert.AreEqual((int)dripRate, tb.DripRate); | 123 | Assert.AreEqual((int)dripRate, tb.DripRate, "Drip rate"); |
104 | Assert.AreEqual((int)maxDripRate, tb.MaxDripRate); | 124 | Assert.AreEqual((int)maxDripRate, tb.MaxDripRate, "Max drip rate"); |
105 | } | 125 | } |
106 | 126 | ||
107 | [Test] | 127 | [Test] |
@@ -360,16 +380,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
360 | // "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}", | 380 | // "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}", |
361 | // ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle); | 381 | // ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle); |
362 | 382 | ||
363 | Assert.AreEqual((int)resendBytes, ci.resendThrottle); | 383 | Assert.AreEqual((int)resendBytes, ci.resendThrottle, "Resend"); |
364 | Assert.AreEqual((int)landBytes, ci.landThrottle); | 384 | Assert.AreEqual((int)landBytes, ci.landThrottle, "Land"); |
365 | Assert.AreEqual((int)windBytes, ci.windThrottle); | 385 | Assert.AreEqual((int)windBytes, ci.windThrottle, "Wind"); |
366 | Assert.AreEqual((int)cloudBytes, ci.cloudThrottle); | 386 | Assert.AreEqual((int)cloudBytes, ci.cloudThrottle, "Cloud"); |
367 | Assert.AreEqual((int)taskBytes, ci.taskThrottle); | 387 | Assert.AreEqual((int)taskBytes, ci.taskThrottle, "Task"); |
368 | Assert.AreEqual((int)textureBytes, ci.textureThrottle); | 388 | Assert.AreEqual((int)textureBytes, ci.textureThrottle, "Texture"); |
369 | Assert.AreEqual((int)assetBytes, ci.assetThrottle); | 389 | Assert.AreEqual((int)assetBytes, ci.assetThrottle, "Asset"); |
370 | Assert.AreEqual((int)totalBytes, ci.totalThrottle); | 390 | Assert.AreEqual((int)totalBytes, ci.totalThrottle, "Total"); |
371 | Assert.AreEqual((int)targetBytes, ci.targetThrottle); | 391 | Assert.AreEqual((int)targetBytes, ci.targetThrottle, "Target"); |
372 | Assert.AreEqual((int)maxBytes, ci.maxThrottle); | 392 | Assert.AreEqual((int)maxBytes, ci.maxThrottle, "Max"); |
373 | } | 393 | } |
374 | 394 | ||
375 | private void SetThrottles( | 395 | private void SetThrottles( |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs index e0633d3..ab8d268 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 | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /// <summary> | 112 | /// <summary> |
113 | /// The speed limit of this bucket in bytes per second. This is the | 113 | /// The requested drip rate for this particular bucket. |
114 | /// number of tokens that are added to the bucket per quantum | ||
115 | /// </summary> | 114 | /// </summary> |
116 | /// <remarks> | 115 | /// <remarks> |
117 | /// RequestedDripRate can never be above MaxDripRate. | 116 | /// 0 then TotalDripRequest is used instead. |
118 | /// Tokens are added to the bucket any time | 117 | /// Can never be above MaxDripRate. |
118 | /// Tokens are added to the bucket at any time | ||
119 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of | 119 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of |
120 | /// the system tick interval (typically around 15-22ms)</remarks> | 120 | /// the system tick interval (typically around 15-22ms) |
121 | /// FIXME: It is extremely confusing to be able to set a RequestedDripRate of 0 and then receive a positive | ||
122 | /// number on get if TotalDripRequest is sent. This also stops us being able to retrieve the fact that | ||
123 | /// RequestedDripRate is set to 0. Really, this should always return m_dripRate and then we can get | ||
124 | /// (m_dripRate == 0 ? TotalDripRequest : m_dripRate) on some other properties. | ||
125 | /// </remarks> | ||
121 | protected Int64 m_dripRate; | 126 | protected Int64 m_dripRate; |
122 | public virtual Int64 RequestedDripRate | 127 | public virtual Int64 RequestedDripRate |
123 | { | 128 | { |
@@ -131,7 +136,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
131 | else | 136 | else |
132 | m_dripRate = value; | 137 | m_dripRate = value; |
133 | 138 | ||
134 | TotalDripRequest = m_dripRate; | ||
135 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); | 139 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); |
136 | 140 | ||
137 | if (Parent != null) | 141 | if (Parent != null) |
@@ -142,15 +146,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
142 | /// <summary> | 146 | /// <summary> |
143 | /// Gets the drip rate. | 147 | /// Gets the drip rate. |
144 | /// </summary> | 148 | /// </summary> |
145 | /// <value>DripRate can never be above max.</value> | 149 | /// <value> |
150 | /// DripRate can never be above max drip rate or below min drip rate. | ||
151 | /// If we are a child bucket then the drip rate return is modifed by the total load on the capacity of the | ||
152 | /// parent bucket. | ||
153 | /// </value> | ||
146 | public virtual Int64 DripRate | 154 | public virtual Int64 DripRate |
147 | { | 155 | { |
148 | get | 156 | get |
149 | { | 157 | { |
158 | double rate; | ||
159 | |||
160 | // FIXME: This doesn't properly work if we have a parent and children and a requested drip rate set | ||
161 | // on ourselves which is not equal to the child drip rates. | ||
150 | if (Parent == null) | 162 | if (Parent == null) |
151 | return Math.Min(RequestedDripRate, TotalDripRequest); | 163 | { |
152 | 164 | if (TotalDripRequest > 0) | |
153 | double rate = (double)RequestedDripRate * Parent.DripRateModifier(); | 165 | rate = Math.Min(RequestedDripRate, TotalDripRequest); |
166 | else | ||
167 | rate = RequestedDripRate; | ||
168 | } | ||
169 | else | ||
170 | { | ||
171 | rate = (double)RequestedDripRate * Parent.DripRateModifier(); | ||
172 | } | ||
173 | |||
154 | if (rate < m_minimumDripRate) | 174 | if (rate < m_minimumDripRate) |
155 | rate = m_minimumDripRate; | 175 | rate = m_minimumDripRate; |
156 | else if (MaxDripRate > 0 && rate > MaxDripRate) | 176 | else if (MaxDripRate > 0 && rate > MaxDripRate) |
@@ -163,18 +183,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
163 | // <summary> | 183 | // <summary> |
164 | // The maximum rate for flow control. Drip rate can never be greater than this. | 184 | // The maximum rate for flow control. Drip rate can never be greater than this. |
165 | // </summary> | 185 | // </summary> |
166 | // protected Int64 m_maxDripRate; | ||
167 | // public Int64 MaxDripRate | ||
168 | // { | ||
169 | // get { return m_maxDripRate; } | ||
170 | // //get { return (m_maxDripRate == 0 ? TotalDripRequest : m_maxDripRate); } | ||
171 | // set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value, m_minimumFlow)); } | ||
172 | // } | ||
173 | public Int64 MaxDripRate { get; set; } | 186 | public Int64 MaxDripRate { get; set; } |
174 | 187 | ||
175 | /// <summary> | 188 | /// <summary> |
176 | /// The current total of the requested maximum burst rates of | 189 | /// The current total of the requested maximum burst rates of children buckets. |
177 | /// this bucket's children buckets. | ||
178 | /// </summary> | 190 | /// </summary> |
179 | public Int64 TotalDripRequest { get; protected set; } | 191 | public Int64 TotalDripRequest { get; protected set; } |
180 | 192 | ||
@@ -197,8 +209,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
197 | Parent = parent; | 209 | Parent = parent; |
198 | RequestedDripRate = dripRate; | 210 | RequestedDripRate = dripRate; |
199 | MaxDripRate = maxDripRate; | 211 | MaxDripRate = maxDripRate; |
200 | // TotalDripRequest = dripRate; // this will be overwritten when a child node registers | ||
201 | // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); | ||
202 | m_lastDrip = Util.EnvironmentTickCount(); | 212 | m_lastDrip = Util.EnvironmentTickCount(); |
203 | } | 213 | } |
204 | 214 | ||
@@ -243,7 +253,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
243 | lock (m_children) | 253 | lock (m_children) |
244 | { | 254 | { |
245 | m_children[child] = request; | 255 | m_children[child] = request; |
246 | // TotalDripRequest = m_children.Values.Sum(); | ||
247 | 256 | ||
248 | TotalDripRequest = 0; | 257 | TotalDripRequest = 0; |
249 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | 258 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) |
@@ -255,12 +264,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
255 | { | 264 | { |
256 | Int64 effectiveDripRate; | 265 | Int64 effectiveDripRate; |
257 | 266 | ||
258 | if (MaxDripRate > 0) | 267 | if (RequestedDripRate > 0) |
259 | effectiveDripRate = Math.Min(MaxDripRate, TotalDripRequest); | 268 | effectiveDripRate = Math.Min(RequestedDripRate, TotalDripRequest); |
260 | else | 269 | else |
261 | effectiveDripRate = TotalDripRequest; | 270 | effectiveDripRate = TotalDripRequest; |
262 | 271 | ||
263 | //Parent.RegisterRequest(this, Math.Min(RequestedDripRate, TotalDripRequest)); | ||
264 | Parent.RegisterRequest(this, effectiveDripRate); | 272 | Parent.RegisterRequest(this, effectiveDripRate); |
265 | } | 273 | } |
266 | } | 274 | } |
@@ -274,7 +282,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
274 | lock (m_children) | 282 | lock (m_children) |
275 | { | 283 | { |
276 | m_children.Remove(child); | 284 | m_children.Remove(child); |
277 | // m_totalDripRequest = m_children.Values.Sum(); | ||
278 | 285 | ||
279 | TotalDripRequest = 0; | 286 | TotalDripRequest = 0; |
280 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | 287 | foreach (KeyValuePair<TokenBucket, Int64> 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 f6772a5..08d0fbf 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 | |||
490 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", | 490 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", |
491 | "Max", | 491 | "Max", |
492 | "Target", | 492 | "Target", |
493 | "Total", | 493 | "Actual", |
494 | "Resend", | 494 | "Resend", |
495 | "Land", | 495 | "Land", |
496 | "Wind", | 496 | "Wind", |
@@ -546,7 +546,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
546 | report.AppendFormat( | 546 | report.AppendFormat( |
547 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", | 547 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", |
548 | ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-", | 548 | ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-", |
549 | llUdpClient.FlowThrottle.AdaptiveEnabled ? ((ci.targetThrottle * 8) / 1000).ToString() : "-", | 549 | llUdpClient.FlowThrottle.AdaptiveEnabled |
550 | ? ((ci.targetThrottle * 8) / 1000).ToString() | ||
551 | : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(), | ||
550 | (ci.totalThrottle * 8) / 1000, | 552 | (ci.totalThrottle * 8) / 1000, |
551 | (ci.resendThrottle * 8) / 1000, | 553 | (ci.resendThrottle * 8) / 1000, |
552 | (ci.landThrottle * 8) / 1000, | 554 | (ci.landThrottle * 8) / 1000, |