diff options
author | John Hurliman | 2009-10-13 19:45:38 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-13 19:45:38 -0700 |
commit | 4135b0c4dcd142fe43b4c1b020d41a72d9df63dd (patch) | |
tree | 0dc6a320589d0486989f0f061a2912db477d51cd /OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |
parent | Optimized heartbeat by calling Update() only on updated objects. (diff) | |
download | opensim-SC_OLD-4135b0c4dcd142fe43b4c1b020d41a72d9df63dd.zip opensim-SC_OLD-4135b0c4dcd142fe43b4c1b020d41a72d9df63dd.tar.gz opensim-SC_OLD-4135b0c4dcd142fe43b4c1b020d41a72d9df63dd.tar.bz2 opensim-SC_OLD-4135b0c4dcd142fe43b4c1b020d41a72d9df63dd.tar.xz |
* Split Task category into Task and State
* Crude prioritization hack
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index b27d8d6..e7707a9 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -59,9 +59,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
59 | /// </summary> | 59 | /// </summary> |
60 | public sealed class LLUDPClient | 60 | public sealed class LLUDPClient |
61 | { | 61 | { |
62 | // FIXME: Make this a config setting | ||
63 | /// <summary>Percentage of the task throttle category that is allocated to avatar and prim | ||
64 | /// state updates</summary> | ||
65 | const float STATE_TASK_PERCENTAGE = 0.8f; | ||
66 | |||
62 | /// <summary>The number of packet categories to throttle on. If a throttle category is added | 67 | /// <summary>The number of packet categories to throttle on. If a throttle category is added |
63 | /// or removed, this number must also change</summary> | 68 | /// or removed, this number must also change</summary> |
64 | const int THROTTLE_CATEGORY_COUNT = 7; | 69 | const int THROTTLE_CATEGORY_COUNT = 8; |
65 | 70 | ||
66 | /// <summary>Fired when updated networking stats are produced for this client</summary> | 71 | /// <summary>Fired when updated networking stats are produced for this client</summary> |
67 | public event PacketStats OnPacketStats; | 72 | public event PacketStats OnPacketStats; |
@@ -134,9 +139,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
134 | /// <summary>An optimization to store the length of dequeued packets being held | 139 | /// <summary>An optimization to store the length of dequeued packets being held |
135 | /// for throttling. This avoids expensive calls to Packet.Length</summary> | 140 | /// for throttling. This avoids expensive calls to Packet.Length</summary> |
136 | private readonly int[] nextPacketLengths = new int[THROTTLE_CATEGORY_COUNT]; | 141 | private readonly int[] nextPacketLengths = new int[THROTTLE_CATEGORY_COUNT]; |
137 | /// <summary>Flags to prevent queue empty callbacks from repeatedly firing | ||
138 | /// before the callbacks have a chance to put packets in the queue</summary> | ||
139 | private readonly bool[] queueEmptySent = new bool[THROTTLE_CATEGORY_COUNT]; | ||
140 | /// <summary>A reference to the LLUDPServer that is managing this client</summary> | 142 | /// <summary>A reference to the LLUDPServer that is managing this client</summary> |
141 | private readonly LLUDPServer udpServer; | 143 | private readonly LLUDPServer udpServer; |
142 | 144 | ||
@@ -167,9 +169,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
167 | throttleCategories[(int)ThrottleOutPacketType.Land] = new TokenBucket(throttle, rates.LandLimit, rates.Land); | 169 | throttleCategories[(int)ThrottleOutPacketType.Land] = new TokenBucket(throttle, rates.LandLimit, rates.Land); |
168 | throttleCategories[(int)ThrottleOutPacketType.Wind] = new TokenBucket(throttle, rates.WindLimit, rates.Wind); | 170 | throttleCategories[(int)ThrottleOutPacketType.Wind] = new TokenBucket(throttle, rates.WindLimit, rates.Wind); |
169 | throttleCategories[(int)ThrottleOutPacketType.Cloud] = new TokenBucket(throttle, rates.CloudLimit, rates.Cloud); | 171 | throttleCategories[(int)ThrottleOutPacketType.Cloud] = new TokenBucket(throttle, rates.CloudLimit, rates.Cloud); |
170 | throttleCategories[(int)ThrottleOutPacketType.Task] = new TokenBucket(throttle, rates.TaskLimit, rates.Task); | ||
171 | throttleCategories[(int)ThrottleOutPacketType.Texture] = new TokenBucket(throttle, rates.TextureLimit, rates.Texture); | 172 | throttleCategories[(int)ThrottleOutPacketType.Texture] = new TokenBucket(throttle, rates.TextureLimit, rates.Texture); |
172 | throttleCategories[(int)ThrottleOutPacketType.Asset] = new TokenBucket(throttle, rates.AssetLimit, rates.Asset); | 173 | throttleCategories[(int)ThrottleOutPacketType.Asset] = new TokenBucket(throttle, rates.AssetLimit, rates.Asset); |
174 | // State and Transaction are actually sub-categories of the LLUDP generic "Task" category | ||
175 | TokenBucket stateBucket = new TokenBucket(throttle, (int)((float)rates.TaskLimit * STATE_TASK_PERCENTAGE), (int)((float)rates.Task * STATE_TASK_PERCENTAGE)); | ||
176 | throttleCategories[(int)ThrottleOutPacketType.State] = stateBucket; | ||
177 | throttleCategories[(int)ThrottleOutPacketType.Task] = new TokenBucket(throttle, rates.TaskLimit - stateBucket.MaxBurst, rates.Task - stateBucket.DripRate); | ||
173 | 178 | ||
174 | // Set the granularity variable used for retransmission calculations to | 179 | // Set the granularity variable used for retransmission calculations to |
175 | // the measured resolution of Environment.TickCount | 180 | // the measured resolution of Environment.TickCount |
@@ -177,6 +182,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
177 | 182 | ||
178 | // Default the retransmission timeout to three seconds | 183 | // Default the retransmission timeout to three seconds |
179 | RTO = 3000; | 184 | RTO = 3000; |
185 | |||
186 | // Initialize this to a sane value to prevent early disconnects | ||
187 | TickLastPacketReceived = Environment.TickCount; | ||
180 | } | 188 | } |
181 | 189 | ||
182 | /// <summary> | 190 | /// <summary> |
@@ -212,7 +220,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
212 | info.landThrottle = throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; | 220 | info.landThrottle = throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; |
213 | info.windThrottle = throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; | 221 | info.windThrottle = throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; |
214 | info.cloudThrottle = throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; | 222 | info.cloudThrottle = throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; |
215 | info.taskThrottle = throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | 223 | info.taskThrottle = throttleCategories[(int)ThrottleOutPacketType.State].DripRate + throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
216 | info.assetThrottle = throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; | 224 | info.assetThrottle = throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; |
217 | info.textureThrottle = throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | 225 | info.textureThrottle = throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; |
218 | info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + | 226 | info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + |
@@ -309,7 +317,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
309 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Land].DripRate), 0, data, i, 4); i += 4; | 317 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Land].DripRate), 0, data, i, 4); i += 4; |
310 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate), 0, data, i, 4); i += 4; | 318 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate), 0, data, i, 4); i += 4; |
311 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate), 0, data, i, 4); i += 4; | 319 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate), 0, data, i, 4); i += 4; |
312 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Task].DripRate), 0, data, i, 4); i += 4; | 320 | Buffer.BlockCopy(Utils.FloatToBytes((float)(throttleCategories[(int)ThrottleOutPacketType.Task].DripRate) + |
321 | throttleCategories[(int)ThrottleOutPacketType.State].DripRate), 0, data, i, 4); i += 4; | ||
313 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate), 0, data, i, 4); i += 4; | 322 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate), 0, data, i, 4); i += 4; |
314 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate), 0, data, i, 4); i += 4; | 323 | Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate), 0, data, i, 4); i += 4; |
315 | 324 | ||
@@ -318,12 +327,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
318 | 327 | ||
319 | public void SetThrottle(ThrottleOutPacketType category, int rate) | 328 | public void SetThrottle(ThrottleOutPacketType category, int rate) |
320 | { | 329 | { |
321 | int i = (int)category; | 330 | if (category == ThrottleOutPacketType.Task) |
322 | if (i >= 0 && i < throttleCategories.Length) | 331 | { |
332 | TokenBucket stateBucket = throttleCategories[(int)ThrottleOutPacketType.State]; | ||
333 | TokenBucket taskBucket = throttleCategories[(int)ThrottleOutPacketType.Task]; | ||
334 | |||
335 | stateBucket.MaxBurst = (int)((float)rate * STATE_TASK_PERCENTAGE); | ||
336 | stateBucket.DripRate = (int)((float)rate * STATE_TASK_PERCENTAGE); | ||
337 | |||
338 | taskBucket.MaxBurst = rate - stateBucket.MaxBurst; | ||
339 | taskBucket.DripRate = rate - stateBucket.DripRate; | ||
340 | } | ||
341 | else | ||
323 | { | 342 | { |
324 | TokenBucket bucket = throttleCategories[(int)category]; | 343 | int i = (int)category; |
325 | bucket.MaxBurst = rate; | 344 | if (i >= 0 && i < throttleCategories.Length) |
326 | bucket.DripRate = rate; | 345 | { |
346 | TokenBucket bucket = throttleCategories[(int)category]; | ||
347 | bucket.MaxBurst = rate; | ||
348 | bucket.DripRate = rate; | ||
349 | } | ||
327 | } | 350 | } |
328 | } | 351 | } |
329 | 352 | ||
@@ -393,10 +416,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
393 | queue = packetOutboxes[i]; | 416 | queue = packetOutboxes[i]; |
394 | if (queue.Dequeue(out packet)) | 417 | if (queue.Dequeue(out packet)) |
395 | { | 418 | { |
396 | // Reset the flag for firing this queue's OnQueueEmpty callback | ||
397 | // now that we have dequeued a packet | ||
398 | queueEmptySent[i] = false; | ||
399 | |||
400 | // A packet was pulled off the queue. See if we have | 419 | // A packet was pulled off the queue. See if we have |
401 | // enough tokens in the bucket to send it out | 420 | // enough tokens in the bucket to send it out |
402 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) | 421 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) |
@@ -458,14 +477,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
458 | 477 | ||
459 | private void FireQueueEmpty(int queueIndex) | 478 | private void FireQueueEmpty(int queueIndex) |
460 | { | 479 | { |
461 | if (!queueEmptySent[queueIndex]) | 480 | QueueEmpty callback = OnQueueEmpty; |
462 | { | 481 | if (callback != null) |
463 | queueEmptySent[queueIndex] = true; | 482 | Util.FireAndForget(delegate(object o) { callback((ThrottleOutPacketType)(int)o); }, queueIndex); |
464 | |||
465 | QueueEmpty callback = OnQueueEmpty; | ||
466 | if (callback != null) | ||
467 | Util.FireAndForget(delegate(object o) { callback((ThrottleOutPacketType)(int)o); }, queueIndex); | ||
468 | } | ||
469 | } | 483 | } |
470 | } | 484 | } |
471 | } | 485 | } |