diff options
author | Justin Clark-Casey (justincc) | 2014-10-28 00:44:03 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2014-11-25 23:22:20 +0000 |
commit | 5ab5d7fe476e39452fc80465ea2506b7b9f7773e (patch) | |
tree | 5e6e8a9f4f4fd49f66694fc9a7948690653cd4a9 /OpenSim/Region/ClientStack/Linden/UDP | |
parent | Fix setting of max scene throttle so that setting it restricts the child clie... (diff) | |
download | opensim-SC-5ab5d7fe476e39452fc80465ea2506b7b9f7773e.zip opensim-SC-5ab5d7fe476e39452fc80465ea2506b7b9f7773e.tar.gz opensim-SC-5ab5d7fe476e39452fc80465ea2506b7b9f7773e.tar.bz2 opensim-SC-5ab5d7fe476e39452fc80465ea2506b7b9f7773e.tar.xz |
Fix recent regression where adaptive throttles stopped adjusting.
Extends regression tests to test response of adaptive throttles to ack'ed and expired packets.
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
3 files changed, 61 insertions, 49 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index c768662..b70d861 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | |||
@@ -447,31 +447,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
447 | long total = resend + land + wind + cloud + task + texture + asset; | 447 | long total = resend + land + wind + cloud + task + texture + asset; |
448 | m_throttleClient.TargetDripRate = total; | 448 | m_throttleClient.TargetDripRate = total; |
449 | } | 449 | } |
450 | else | ||
451 | { | ||
452 | TokenBucket bucket; | ||
453 | 450 | ||
454 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; | 451 | TokenBucket bucket; |
455 | bucket.RequestedDripRate = resend; | ||
456 | 452 | ||
457 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; | 453 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
458 | bucket.RequestedDripRate = land; | 454 | bucket.RequestedDripRate = resend; |
459 | 455 | ||
460 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; | 456 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; |
461 | bucket.RequestedDripRate = wind; | 457 | bucket.RequestedDripRate = land; |
462 | 458 | ||
463 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; | 459 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; |
464 | bucket.RequestedDripRate = cloud; | 460 | bucket.RequestedDripRate = wind; |
465 | 461 | ||
466 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; | 462 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; |
467 | bucket.RequestedDripRate = asset; | 463 | bucket.RequestedDripRate = cloud; |
468 | 464 | ||
469 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; | 465 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; |
470 | bucket.RequestedDripRate = task; | 466 | bucket.RequestedDripRate = asset; |
471 | 467 | ||
472 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | 468 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; |
473 | bucket.RequestedDripRate = texture; | 469 | bucket.RequestedDripRate = task; |
474 | } | 470 | |
471 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | ||
472 | bucket.RequestedDripRate = texture; | ||
475 | 473 | ||
476 | // Reset the packed throttles cached data | 474 | // Reset the packed throttles cached data |
477 | m_packedThrottles = null; | 475 | m_packedThrottles = null; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs index 912c994..0560b9b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs | |||
@@ -184,7 +184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
184 | udpServer.Throttle.DebugLevel = 1; | 184 | udpServer.Throttle.DebugLevel = 1; |
185 | udpClient.ThrottleDebugLevel = 1; | 185 | udpClient.ThrottleDebugLevel = 1; |
186 | 186 | ||
187 | // Total is 28000 | 187 | // Total is 280000 |
188 | int resendBytes = 10000; | 188 | int resendBytes = 10000; |
189 | int landBytes = 20000; | 189 | int landBytes = 20000; |
190 | int windBytes = 30000; | 190 | int windBytes = 30000; |
@@ -192,24 +192,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
192 | int taskBytes = 50000; | 192 | int taskBytes = 50000; |
193 | int textureBytes = 60000; | 193 | int textureBytes = 60000; |
194 | int assetBytes = 70000; | 194 | int assetBytes = 70000; |
195 | int totalBytes = resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes; | ||
195 | 196 | ||
196 | SetThrottles( | 197 | SetThrottles( |
197 | udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | 198 | udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); |
198 | 199 | ||
199 | // We expect individual throttle changes to currently have no effect under adaptive, since this is managed | 200 | // Ratio of current adaptive drip rate to requested bytes |
200 | // purely by that throttle. However, we expect the max to change. | 201 | // XXX: Should hard code this as below so we don't rely on values given by tested code to construct |
201 | // XXX: At the moment we check against defaults, but at some point there should be a better test to | 202 | // expected values. |
202 | // active see change over time. | 203 | double commitRatio = (double)udpClient.FlowThrottle.AdjustedDripRate / udpClient.FlowThrottle.TargetDripRate; |
203 | ThrottleRates defaultRates = udpServer.ThrottleRates; | 204 | |
205 | AssertThrottles( | ||
206 | udpClient, | ||
207 | LLUDPServer.MTU, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio, | ||
208 | textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0); | ||
209 | |||
210 | // Test an increase in target throttle | ||
211 | udpClient.FlowThrottle.AcknowledgePackets(35000); | ||
212 | commitRatio = 0.2; | ||
213 | |||
214 | AssertThrottles( | ||
215 | udpClient, | ||
216 | resendBytes * commitRatio, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio, | ||
217 | textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0); | ||
204 | 218 | ||
205 | // Current total is 66750 | 219 | // Test a decrease in target throttle |
206 | int totalBytes = defaultRates.Resend + defaultRates.Land + defaultRates.Wind + defaultRates.Cloud + defaultRates.Task + defaultRates.Texture + defaultRates.Asset; | 220 | udpClient.FlowThrottle.ExpirePackets(1); |
207 | int totalMaxBytes = resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes; | 221 | commitRatio = 0.1; |
208 | 222 | ||
209 | AssertThrottles( | 223 | AssertThrottles( |
210 | udpClient, | 224 | udpClient, |
211 | defaultRates.Resend, defaultRates.Land, defaultRates.Wind, defaultRates.Cloud, defaultRates.Task, | 225 | LLUDPServer.MTU, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio, |
212 | defaultRates.Texture, defaultRates.Asset, totalBytes, totalMaxBytes, 0); | 226 | textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0); |
213 | } | 227 | } |
214 | 228 | ||
215 | /// <summary> | 229 | /// <summary> |
@@ -376,9 +390,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
376 | { | 390 | { |
377 | ClientInfo ci = udpClient.GetClientInfo(); | 391 | ClientInfo ci = udpClient.GetClientInfo(); |
378 | 392 | ||
379 | // Console.WriteLine( | 393 | // Console.WriteLine( |
380 | // "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}", | 394 | // "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}", |
381 | // ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle); | 395 | // ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle); |
382 | 396 | ||
383 | Assert.AreEqual((int)resendBytes, ci.resendThrottle, "Resend"); | 397 | Assert.AreEqual((int)resendBytes, ci.resendThrottle, "Resend"); |
384 | Assert.AreEqual((int)landBytes, ci.landThrottle, "Land"); | 398 | Assert.AreEqual((int)landBytes, ci.landThrottle, "Land"); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs index ab8d268..d215595 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs | |||
@@ -76,8 +76,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
76 | /// Map of children buckets and their requested maximum burst rate | 76 | /// Map of children buckets and their requested maximum burst rate |
77 | /// </summary> | 77 | /// </summary> |
78 | protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>(); | 78 | protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>(); |
79 | |||
80 | #region Properties | ||
81 | 79 | ||
82 | /// <summary> | 80 | /// <summary> |
83 | /// The parent bucket of this bucket, or null if this bucket has no | 81 | /// The parent bucket of this bucket, or null if this bucket has no |
@@ -123,7 +121,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
123 | /// RequestedDripRate is set to 0. Really, this should always return m_dripRate and then we can get | 121 | /// 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. | 122 | /// (m_dripRate == 0 ? TotalDripRequest : m_dripRate) on some other properties. |
125 | /// </remarks> | 123 | /// </remarks> |
126 | protected Int64 m_dripRate; | ||
127 | public virtual Int64 RequestedDripRate | 124 | public virtual Int64 RequestedDripRate |
128 | { | 125 | { |
129 | get { return (m_dripRate == 0 ? TotalDripRequest : m_dripRate); } | 126 | get { return (m_dripRate == 0 ? TotalDripRequest : m_dripRate); } |
@@ -179,6 +176,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
179 | return (Int64)rate; | 176 | return (Int64)rate; |
180 | } | 177 | } |
181 | } | 178 | } |
179 | protected Int64 m_dripRate; | ||
182 | 180 | ||
183 | // <summary> | 181 | // <summary> |
184 | // The maximum rate for flow control. Drip rate can never be greater than this. | 182 | // The maximum rate for flow control. Drip rate can never be greater than this. |
@@ -189,10 +187,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
189 | /// The current total of the requested maximum burst rates of children buckets. | 187 | /// The current total of the requested maximum burst rates of children buckets. |
190 | /// </summary> | 188 | /// </summary> |
191 | public Int64 TotalDripRequest { get; protected set; } | 189 | public Int64 TotalDripRequest { get; protected set; } |
192 | |||
193 | #endregion Properties | ||
194 | |||
195 | #region Constructor | ||
196 | 190 | ||
197 | /// <summary> | 191 | /// <summary> |
198 | /// Default constructor | 192 | /// Default constructor |
@@ -200,20 +194,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
200 | /// <param name="identifier">Identifier for this token bucket</param> | 194 | /// <param name="identifier">Identifier for this token bucket</param> |
201 | /// <param name="parent">Parent bucket if this is a child bucket, or | 195 | /// <param name="parent">Parent bucket if this is a child bucket, or |
202 | /// null if this is a root bucket</param> | 196 | /// null if this is a root bucket</param> |
203 | /// <param name="dripRate">Rate that the bucket fills, in bytes per | 197 | /// <param name="requestedDripRate"> |
204 | /// second. If zero, the bucket always remains full</param> | 198 | /// Requested rate that the bucket fills, in bytes per |
205 | public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate, Int64 maxDripRate) | 199 | /// second. If zero, the bucket always remains full. |
200 | /// </param> | ||
201 | public TokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate) | ||
206 | { | 202 | { |
207 | Identifier = identifier; | 203 | Identifier = identifier; |
208 | 204 | ||
209 | Parent = parent; | 205 | Parent = parent; |
210 | RequestedDripRate = dripRate; | 206 | RequestedDripRate = requestedDripRate; |
211 | MaxDripRate = maxDripRate; | 207 | MaxDripRate = maxDripRate; |
212 | m_lastDrip = Util.EnvironmentTickCount(); | 208 | m_lastDrip = Util.EnvironmentTickCount(); |
213 | } | 209 | } |
214 | 210 | ||
215 | #endregion Constructor | ||
216 | |||
217 | /// <summary> | 211 | /// <summary> |
218 | /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning | 212 | /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning |
219 | /// no modification if the requested bandwidth is less than the | 213 | /// no modification if the requested bandwidth is less than the |
@@ -374,7 +368,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
374 | public Int64 TargetDripRate | 368 | public Int64 TargetDripRate |
375 | { | 369 | { |
376 | get { return m_targetDripRate; } | 370 | get { return m_targetDripRate; } |
377 | set { m_targetDripRate = Math.Max(0, value); } | 371 | set |
372 | { | ||
373 | m_targetDripRate = Math.Max(value, m_minimumFlow); | ||
374 | } | ||
378 | } | 375 | } |
379 | protected Int64 m_targetDripRate; | 376 | protected Int64 m_targetDripRate; |
380 | 377 | ||
@@ -384,9 +381,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
384 | public virtual Int64 AdjustedDripRate | 381 | public virtual Int64 AdjustedDripRate |
385 | { | 382 | { |
386 | get { return m_dripRate; } | 383 | get { return m_dripRate; } |
387 | set { | 384 | set |
385 | { | ||
388 | m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value, m_minimumFlow, TargetDripRate); | 386 | m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value, m_minimumFlow, TargetDripRate); |
389 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); | 387 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); |
388 | |||
390 | if (Parent != null) | 389 | if (Parent != null) |
391 | Parent.RegisterRequest(this, m_dripRate); | 390 | Parent.RegisterRequest(this, m_dripRate); |
392 | } | 391 | } |
@@ -399,14 +398,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
399 | /// </summary> | 398 | /// </summary> |
400 | protected const Int64 m_minimumFlow = m_minimumDripRate * 15; | 399 | protected const Int64 m_minimumFlow = m_minimumDripRate * 15; |
401 | 400 | ||
402 | public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 dripRate, Int64 maxDripRate, bool enabled) | 401 | public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate, bool enabled) |
403 | : base(identifier, parent, dripRate, maxDripRate) | 402 | : base(identifier, parent, requestedDripRate, maxDripRate) |
404 | { | 403 | { |
405 | AdaptiveEnabled = enabled; | 404 | AdaptiveEnabled = enabled; |
406 | 405 | ||
407 | if (AdaptiveEnabled) | 406 | if (AdaptiveEnabled) |
408 | { | 407 | { |
409 | // m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled"); | 408 | // m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled"); |
409 | TargetDripRate = m_minimumFlow; | ||
410 | AdjustedDripRate = m_minimumFlow; | 410 | AdjustedDripRate = m_minimumFlow; |
411 | } | 411 | } |
412 | } | 412 | } |