From 2b737c9cc2e4a4ef3520d80225381a010bd1dc80 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 20 Apr 2011 16:23:33 -0700 Subject: Adds the first pass at an adaptive throttle to slow start new clients. If the sent packets are ack'ed successfully the throttle will open quickly up to the maximum specified by the client and/or the sims client throttle. This still needs a lot of adjustment to get the rates correct. --- OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 7be8a0a..20bfec8 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -135,7 +135,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_nextOnQueueEmpty = 1; /// Throttle bucket for this agent's connection - private readonly TokenBucket m_throttleClient; + private readonly AdaptiveTokenBucket m_throttleClient; + public AdaptiveTokenBucket FlowThrottle + { + get { return m_throttleClient; } + } + /// Throttle bucket for this agent's connection private readonly TokenBucket m_throttleCategory; /// Throttle buckets for each packet category @@ -176,7 +181,7 @@ 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 TokenBucket(parentThrottle, rates.TotalLimit); + m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.TotalLimit); // Create a token bucket throttle for the total categary with the client bucket as a throttle m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit); // Create an array of token buckets for this clients different throttle categories -- cgit v1.1 From 3534f4492ae747baff492f4bc10bf06994ee1bc6 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 22 Apr 2011 14:01:12 -0700 Subject: Various clean ups. Removed some debugging code. Added a new "show pqueues" command to look at the entity update priority queue. Added a "name" parameter to show queues, show pqueues and show throttles to look at data for a specific user. --- .../Region/ClientStack/LindenUDP/LLUDPClient.cs | 24 +--------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 20bfec8..103ec66 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -228,26 +228,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Information about the client connection public ClientInfo GetClientInfo() { -/// - TokenBucket tb; - - tb = m_throttleClient.Parent; - m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest,"ROOT"); - - tb = m_throttleClient; - m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CLIENT"); - - tb = m_throttleCategory; - m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CATEGORY"); - - for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) - { - tb = m_throttleCategories[i]; - m_log.WarnFormat("[TOKENS] {4} <{0}:{1}>: Actual={2},Requested={3}",AgentID,i,tb.DripRate,tb.RequestedDripRate," BUCKET"); - } - -/// - // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists // of pending and needed ACKs for every client every time some method wants information about // this connection is a recipe for poor performance @@ -259,12 +239,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; - // info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; - info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + - info.taskThrottle + info.assetThrottle + info.textureThrottle; + info.totalThrottle = (int)m_throttleCategory.DripRate; return info; } -- cgit v1.1 From 024c12abc3aa42432e55e322141cad1edeb5bad1 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 25 Apr 2011 10:44:41 -0700 Subject: Cleaned up various configuration options. Removed the category throttle limits because the only ones used now are the defaults (which are overwritten by the client throttles anyway). Updated the default rates to correspond to about 350kbps. Also added a configuration to disable adaptive throttle. The default is the previous behavior (no adaptation). --- OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 103ec66..494cb0c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -181,9 +181,9 @@ 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.TotalLimit); + m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); // Create a token bucket throttle for the total categary with the client bucket as a throttle - m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit); + m_throttleCategory = new TokenBucket(m_throttleClient, rates.Total); // Create an array of token buckets for this clients different throttle categories m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; @@ -194,7 +194,7 @@ 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.GetLimit(type)); + m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); } // Default the retransmission timeout to three seconds @@ -341,12 +341,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP task = Math.Max(task, LLUDPServer.MTU); texture = Math.Max(texture, LLUDPServer.MTU); asset = Math.Max(asset, LLUDPServer.MTU); - state = Math.Max(state, LLUDPServer.MTU); - int total = resend + land + wind + cloud + task + texture + asset + state; + 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}, State={8}, Total={9}", - // AgentID, resend, land, wind, cloud, task, texture, asset, state, total); + //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); // Update the token buckets with new throttle values TokenBucket bucket; -- cgit v1.1 From 77ab7ce084d32c45273d79e9ec4f52c43e3a1d97 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 25 Apr 2011 15:11:29 -0700 Subject: Fixed the transmission of throttles from root agent to child agents. Child throttles are based on the number of child agents known to the root and at least 1/4 of the throttle given to the root. --- .../Region/ClientStack/LindenUDP/LLUDPClient.cs | 40 ++++++++++++++-------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 494cb0c..50f1e2c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -329,8 +329,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); // State is a subcategory of task that we allocate a percentage to int state = 0; - // int state = (int)((float)task * STATE_TASK_PERCENTAGE); - // task -= state; // Make sure none of the throttles are set below our packet MTU, // otherwise a throttle could become permanently clogged @@ -342,17 +340,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP texture = Math.Max(texture, LLUDPServer.MTU); asset = Math.Max(asset, LLUDPServer.MTU); - int total = resend + land + wind + cloud + task + texture + asset; - + //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); // Update the token buckets with new throttle values TokenBucket bucket; - bucket = m_throttleCategory; - bucket.RequestedDripRate = total; - bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; bucket.RequestedDripRate = resend; @@ -381,22 +375,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_packedThrottles = null; } - public byte[] GetThrottlesPacked() + public byte[] GetThrottlesPacked(float multiplier) { byte[] data = m_packedThrottles; if (data == null) { + float rate; + data = new byte[7 * 4]; int i = 0; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate), 0, data, i, 4); i += 4; + // multiply by 8 to convert bytes back to bits + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * 8 * multiplier; + Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; m_packedThrottles = data; } -- cgit v1.1 From 13f141a4d521fc15618c2983c989805d9174b969 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 25 Apr 2011 15:36:59 -0700 Subject: Fix the totals shown by show throttle --- OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 50f1e2c..ca5501d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // 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); // Create a token bucket throttle for the total categary with the client bucket as a throttle - m_throttleCategory = new TokenBucket(m_throttleClient, rates.Total); + m_throttleCategory = new TokenBucket(m_throttleClient, 0); // Create an array of token buckets for this clients different throttle categories m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; -- cgit v1.1