* Plumbing and basic setting of the GetMesh Cap Throttler.

* Last step is to flip the throttle distribution.
avinationmerge
teravus 2012-11-17 03:47:09 -05:00
parent e9153e1d1a
commit 5e0294815f
8 changed files with 127 additions and 19 deletions

View File

@ -152,6 +152,7 @@ namespace OpenSim.Capabilities.Handlers
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
responsedata["str_response_string"] = "This range doesnt exist."; responsedata["str_response_string"] = "This range doesnt exist.";
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
return responsedata; return responsedata;
} }
else else
@ -162,14 +163,28 @@ namespace OpenSim.Capabilities.Handlers
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
if (start > 20000)
{
responsedata["int_lod"] = 3;
}
else if (start < 4097)
{
responsedata["int_lod"] = 1;
}
else
{
responsedata["int_lod"] = 2;
}
if (start == 0 && len == mesh.Data.Length) // well redudante maybe if (start == 0 && len == mesh.Data.Length) // well redudante maybe
{ {
responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK; responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK;
responsedata["bin_response_data"] = mesh.Data; responsedata["bin_response_data"] = mesh.Data;
responsedata["int_bytes"] = mesh.Data.Length; responsedata["int_bytes"] = mesh.Data.Length;
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
} }
else else
{ {
@ -193,6 +208,7 @@ namespace OpenSim.Capabilities.Handlers
responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["content_type"] = "application/vnd.ll.mesh";
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
} }
} }
else else
@ -201,6 +217,7 @@ namespace OpenSim.Capabilities.Handlers
responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["content_type"] = "application/vnd.ll.mesh";
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
} }
} }
// Optionally add additional mesh types here // Optionally add additional mesh types here
@ -211,6 +228,7 @@ namespace OpenSim.Capabilities.Handlers
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["int_lod"] = 1;
return responsedata; return responsedata;
} }
} }
@ -221,6 +239,7 @@ namespace OpenSim.Capabilities.Handlers
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["int_lod"] = 0;
return responsedata; return responsedata;
} }
} }

View File

@ -1135,6 +1135,8 @@ namespace OpenSim.Framework
void SetChildAgentThrottle(byte[] throttle); void SetChildAgentThrottle(byte[] throttle);
void SetAgentThrottleSilent(int throttle, int setting);
void SendAvatarDataImmediate(ISceneEntity avatar); void SendAvatarDataImmediate(ISceneEntity avatar);
/// <summary> /// <summary>

View File

@ -60,6 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden
private IAssetService m_AssetService; private IAssetService m_AssetService;
private bool m_Enabled = true; private bool m_Enabled = true;
private string m_URL; private string m_URL;
struct aPollRequest struct aPollRequest
{ {
public PollServiceMeshEventArgs thepoll; public PollServiceMeshEventArgs thepoll;
@ -71,6 +72,7 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
public Hashtable response; public Hashtable response;
public int bytes; public int bytes;
public int lod;
} }
@ -112,6 +114,7 @@ namespace OpenSim.Region.ClientStack.Linden
// Cap doesn't exist // Cap doesn't exist
if (m_URL != string.Empty) if (m_URL != string.Empty)
m_Enabled = true; m_Enabled = true;
} }
public void AddRegion(Scene pScene) public void AddRegion(Scene pScene)
@ -192,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden
PollServiceMeshEventArgs args; PollServiceMeshEventArgs args;
if (m_pollservices.TryGetValue(user, out args)) if (m_pollservices.TryGetValue(user, out args))
{ {
args.UpdateThrottle(imagethrottle); args.UpdateThrottle(imagethrottle, p);
} }
} }
@ -242,11 +245,12 @@ namespace OpenSim.Region.ClientStack.Linden
new Dictionary<UUID, aPollResponse>(); new Dictionary<UUID, aPollResponse>();
private Scene m_scene; private Scene m_scene;
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000, 10000); private MeshCapsDataThrottler m_throttler;
public PollServiceMeshEventArgs(UUID pId, Scene scene) : public PollServiceMeshEventArgs(UUID pId, Scene scene) :
base(null, null, null, null, pId, int.MaxValue) base(null, null, null, null, pId, int.MaxValue)
{ {
m_scene = scene; m_scene = scene;
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene);
// x is request id, y is userid // x is request id, y is userid
HasEvents = (x, y) => HasEvents = (x, y) =>
{ {
@ -268,6 +272,7 @@ namespace OpenSim.Region.ClientStack.Linden
} }
finally finally
{ {
m_throttler.ProcessTime();
responses.Remove(x); responses.Remove(x);
} }
} }
@ -323,7 +328,7 @@ namespace OpenSim.Region.ClientStack.Linden
response["reusecontext"] = false; response["reusecontext"] = false;
lock (responses) lock (responses)
responses[requestID] = new aPollResponse() { bytes = 0, response = response }; responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
return; return;
} }
@ -334,6 +339,7 @@ namespace OpenSim.Region.ClientStack.Linden
responses[requestID] = new aPollResponse() responses[requestID] = new aPollResponse()
{ {
bytes = (int)response["int_bytes"], bytes = (int)response["int_bytes"],
lod = (int)response["int_lod"],
response = response response = response
}; };
@ -341,9 +347,9 @@ namespace OpenSim.Region.ClientStack.Linden
m_throttler.ProcessTime(); m_throttler.ProcessTime();
} }
internal void UpdateThrottle(int pimagethrottle) internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
{ {
m_throttler.ThrottleBytes = pimagethrottle; m_throttler.UpdateThrottle(pimagethrottle, p);
} }
} }
@ -398,18 +404,31 @@ namespace OpenSim.Region.ClientStack.Linden
} }
} }
internal sealed class CapsDataThrottler internal sealed class MeshCapsDataThrottler
{ {
private volatile int currenttime = 0; private volatile int currenttime = 0;
private volatile int lastTimeElapsed = 0; private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0; private volatile int BytesSent = 0;
private int oversizedImages = 0; private int Lod3 = 0;
public CapsDataThrottler(int pBytes, int max, int min) private int Lod2 = 0;
private int Lod1 = 0;
private int UserSetThrottle = 0;
private int UDPSetThrottle = 0;
private int CapSetThrottle = 0;
private float CapThrottleDistributon = 0.30f;
private readonly Scene m_scene;
private ThrottleOutPacketType Throttle;
public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene)
{ {
ThrottleBytes = pBytes; ThrottleBytes = pBytes;
lastTimeElapsed = Util.EnvironmentTickCount(); lastTimeElapsed = Util.EnvironmentTickCount();
Throttle = ThrottleOutPacketType.Task;
m_scene = pScene;
} }
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses) public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
{ {
PassTime(); PassTime();
@ -427,17 +446,23 @@ namespace OpenSim.Region.ClientStack.Linden
if (BytesSent + response.bytes <= ThrottleBytes) if (BytesSent + response.bytes <= ThrottleBytes)
{ {
BytesSent += response.bytes; BytesSent += response.bytes;
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
//m_actions.Add(timeBasedAction);
return true; return true;
} }
// Big textures // Lod3 Over
else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1)) else if (response.bytes > ThrottleBytes && Lod3 <= (((ThrottleBytes * .30f) % 50000) + 1))
{ {
Interlocked.Increment(ref oversizedImages); Interlocked.Increment(ref Lod3);
BytesSent += response.bytes; BytesSent += response.bytes;
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
//m_actions.Add(timeBasedAction); return true;
}
// Lod2 Over
else if (response.bytes > ThrottleBytes && Lod2 <= (((ThrottleBytes * .30f) % 10000) + 1))
{
Interlocked.Increment(ref Lod2);
BytesSent += response.bytes;
return true; return true;
} }
else else
@ -448,6 +473,11 @@ namespace OpenSim.Region.ClientStack.Linden
return haskey; return haskey;
} }
public void SubtractBytes(int bytes,int lod)
{
BytesSent -= bytes;
}
public void ProcessTime() public void ProcessTime()
{ {
PassTime(); PassTime();
@ -459,18 +489,42 @@ namespace OpenSim.Region.ClientStack.Linden
currenttime = Util.EnvironmentTickCount(); currenttime = Util.EnvironmentTickCount();
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed); int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
//processTimeBasedActions(responses); //processTimeBasedActions(responses);
if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000) if (currenttime - timeElapsed >= 1000)
{ {
lastTimeElapsed = Util.EnvironmentTickCount(); lastTimeElapsed = Util.EnvironmentTickCount();
BytesSent -= ThrottleBytes; BytesSent -= ThrottleBytes;
if (BytesSent < 0) BytesSent = 0; if (BytesSent < 0) BytesSent = 0;
if (BytesSent < ThrottleBytes) if (BytesSent < ThrottleBytes)
{ {
oversizedImages = 0; Lod3 = 0;
Lod2 = 0;
Lod1 = 0;
} }
} }
} }
public int ThrottleBytes; private void AlterThrottle(int setting, ScenePresence p)
{
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
}
public int ThrottleBytes
{
get { return CapSetThrottle; }
set { CapSetThrottle = value; }
}
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
{
// Client set throttle !
UserSetThrottle = pimagethrottle;
CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
if (CapSetThrottle < 4068)
CapSetThrottle = 4068; // at least two discovery mesh
p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
ProcessTime();
}
} }
} }

View File

@ -11883,6 +11883,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
/// <summary>
/// Sets the throttles from values supplied by the client
/// </summary>
/// <param name="throttles"></param>
public void SetAgentThrottleSilent(int throttle, int setting)
{
m_udpClient.ForceThrottleSetting(throttle,setting);
//m_udpClient.SetThrottles(throttles);
}
/// <summary> /// <summary>
/// Get the current throttles for this client as a packed byte array /// Get the current throttles for this client as a packed byte array
/// </summary> /// </summary>

View File

@ -682,6 +682,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_nextOnQueueEmpty == 0) if (m_nextOnQueueEmpty == 0)
m_nextOnQueueEmpty = 1; m_nextOnQueueEmpty = 1;
} }
internal void ForceThrottleSetting(int throttle, int setting)
{
m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
}
/// <summary> /// <summary>
/// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a

View File

@ -1428,6 +1428,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
} }
public void SetAgentThrottleSilent(int throttle, int setting)
{
}
public byte[] GetThrottlesPacked(float multiplier) public byte[] GetThrottlesPacked(float multiplier)
{ {
return new byte[0]; return new byte[0];

View File

@ -596,6 +596,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public virtual void SetChildAgentThrottle(byte[] throttle) public virtual void SetChildAgentThrottle(byte[] throttle)
{ {
}
public void SetAgentThrottleSilent(int throttle, int setting)
{
} }
public byte[] GetThrottlesPacked(float multiplier) public byte[] GetThrottlesPacked(float multiplier)
{ {

View File

@ -520,6 +520,12 @@ namespace OpenSim.Tests.Common.Mock
public virtual void SetChildAgentThrottle(byte[] throttle) public virtual void SetChildAgentThrottle(byte[] throttle)
{ {
}
public void SetAgentThrottleSilent(int throttle, int setting)
{
} }
public byte[] GetThrottlesPacked(float multiplier) public byte[] GetThrottlesPacked(float multiplier)
{ {