A few updates necessary for load balancer.

- handle GetUser request for nonexistent user gracefully
- include throttle levels in ClientInfo
- code to save/restore throttles in client stack
- only update/send updates to active clients
- make animation classes serializable
GenericGridServerConcept
Mike Mazur 2009-02-25 00:32:26 +00:00
parent d81fb565c1
commit bdf95e54a2
9 changed files with 98 additions and 49 deletions

View File

@ -45,5 +45,14 @@ namespace OpenSim.Framework
public uint sequence; public uint sequence;
public byte[] usecircuit; public byte[] usecircuit;
public EndPoint userEP; public EndPoint userEP;
public int resendThrottle;
public int landThrottle;
public int windThrottle;
public int cloudThrottle;
public int taskThrottle;
public int assetThrottle;
public int textureThrottle;
public int totalThrottle;
} }
} }

View File

@ -248,6 +248,9 @@ namespace OpenSim.Grid.UserServer.Modules
{ {
string query = (string) requestData["avatar_name"]; string query = (string) requestData["avatar_name"];
if (null == query)
return CreateUnknownUserErrorResponse();
// Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]"); // Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
string[] querysplit = query.Split(' '); string[] querysplit = query.Split(' ');

View File

@ -561,8 +561,12 @@ namespace OpenSim
{ {
int port = regionInfo.InternalEndPoint.Port; int port = regionInfo.InternalEndPoint.Port;
// set initial originRegionID to RegionID in RegionInfo. (it needs for loding prims) // set initial RegionID to originRegionID in RegionInfo. (it needs for loding prims)
regionInfo.originRegionID = regionInfo.RegionID; // Commented this out because otherwise regions can't register with
// the grid as there is already another region with the same UUID
// at those coordinates. This is required for the load balancer to work.
// --Mike, 2009.02.25
//regionInfo.originRegionID = regionInfo.RegionID;
// set initial ServerURI // set initial ServerURI
regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.InternalEndPoint.Port; regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.InternalEndPoint.Port;

View File

@ -2584,6 +2584,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendCoarseLocationUpdate(List<Vector3> CoarseLocations) public void SendCoarseLocationUpdate(List<Vector3> CoarseLocations)
{ {
if (!IsActive) return; // We don't need to update inactive clients.
CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate); CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
// TODO: don't create new blocks if recycling an old packet // TODO: don't create new blocks if recycling an old packet
int total = CoarseLocations.Count; int total = CoarseLocations.Count;

View File

@ -196,13 +196,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// configuration! // configuration!
// //
if ((m_SynchronizeClient != null) && (!m_Client.IsActive))
{
if (m_SynchronizeClient(m_Client.Scene, packet,
m_Client.AgentId, throttlePacketType))
return;
}
packet.Header.Sequence = 0; packet.Header.Sequence = 0;
lock (m_NeedAck) lock (m_NeedAck)
@ -480,26 +473,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet == null) if (packet == null)
return; return;
// If this client is on another partial instance, no need
// to handle packets
//
if (!m_Client.IsActive && packet.Type != PacketType.LogoutRequest)
{
PacketPool.Instance.ReturnPacket(packet);
return;
}
// Any packet can have some packet acks in the header.
// Process them here
//
if (packet.Header.AppendedAcks)
{
foreach (uint id in packet.Header.AckList)
{
ProcessAck(id);
}
}
// When too many acks are needed to be sent, the client sends // When too many acks are needed to be sent, the client sends
// a packet consisting of acks only // a packet consisting of acks only
// //
@ -516,7 +489,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
PacketPool.Instance.ReturnPacket(packet); PacketPool.Instance.ReturnPacket(packet);
return; return;
} }
else if (packet.Type == PacketType.StartPingCheck)
// Any packet can have some packet acks in the header.
// Process them here
//
if (packet.Header.AppendedAcks)
{
foreach (uint id in packet.Header.AckList)
{
ProcessAck(id);
}
}
// If this client is on another partial instance, no need
// to handle packets
//
if (!m_Client.IsActive && packet.Type != PacketType.LogoutRequest)
{
PacketPool.Instance.ReturnPacket(packet);
return;
}
if (packet.Type == PacketType.StartPingCheck)
{ {
StartPingCheckPacket startPing = (StartPingCheckPacket)packet; StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
CompletePingCheckPacket endPing CompletePingCheckPacket endPing
@ -639,6 +633,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
info.sequence = m_Sequence; info.sequence = m_Sequence;
float multiplier = m_PacketQueue.ThrottleMultiplier;
info.resendThrottle = (int) (m_PacketQueue.ResendThrottle.Throttle / multiplier);
info.landThrottle = (int) (m_PacketQueue.LandThrottle.Throttle / multiplier);
info.windThrottle = (int) (m_PacketQueue.WindThrottle.Throttle / multiplier);
info.cloudThrottle = (int) (m_PacketQueue.CloudThrottle.Throttle / multiplier);
info.taskThrottle = (int) (m_PacketQueue.TaskThrottle.Throttle / multiplier);
info.assetThrottle = (int) (m_PacketQueue.AssetThrottle.Throttle / multiplier);
info.textureThrottle = (int) (m_PacketQueue.TextureThrottle.Throttle / multiplier);
info.totalThrottle = (int) (m_PacketQueue.TotalThrottle.Throttle / multiplier);
return info; return info;
} }
@ -676,6 +680,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
m_Sequence = info.sequence; m_Sequence = info.sequence;
m_PacketQueue.ResendThrottle.Throttle = info.resendThrottle;
m_PacketQueue.LandThrottle.Throttle = info.landThrottle;
m_PacketQueue.WindThrottle.Throttle = info.windThrottle;
m_PacketQueue.CloudThrottle.Throttle = info.cloudThrottle;
m_PacketQueue.TaskThrottle.Throttle = info.taskThrottle;
m_PacketQueue.AssetThrottle.Throttle = info.assetThrottle;
m_PacketQueue.TextureThrottle.Throttle = info.textureThrottle;
m_PacketQueue.TotalThrottle.Throttle = info.totalThrottle;
} }
public void AddImportantPacket(PacketType type) public void AddImportantPacket(PacketType type)

View File

@ -69,18 +69,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// This value also determines how many times per throttletimems the timer will run // This value also determines how many times per throttletimems the timer will run
// If throttleimems is 1000 ms, then the timer will fire every 1000/7 milliseconds // If throttleimems is 1000 ms, then the timer will fire every 1000/7 milliseconds
private float throttleMultiplier = 2.0f; // Default value really doesn't matter.
private int throttleTimeDivisor = 7; private int throttleTimeDivisor = 7;
private int throttletimems = 1000; private int throttletimems = 1000;
private LLPacketThrottle ResendThrottle; internal LLPacketThrottle ResendThrottle;
private LLPacketThrottle LandThrottle; internal LLPacketThrottle LandThrottle;
private LLPacketThrottle WindThrottle; internal LLPacketThrottle WindThrottle;
private LLPacketThrottle CloudThrottle; internal LLPacketThrottle CloudThrottle;
private LLPacketThrottle TaskThrottle; internal LLPacketThrottle TaskThrottle;
private LLPacketThrottle AssetThrottle; internal LLPacketThrottle AssetThrottle;
private LLPacketThrottle TextureThrottle; internal LLPacketThrottle TextureThrottle;
private LLPacketThrottle TotalThrottle; internal LLPacketThrottle TotalThrottle;
// private long LastThrottle; // private long LastThrottle;
// private long ThrottleInterval; // private long ThrottleInterval;
@ -108,6 +109,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
TextureOutgoingPacketQueue = new Queue<LLQueItem>(); TextureOutgoingPacketQueue = new Queue<LLQueItem>();
AssetOutgoingPacketQueue = new Queue<LLQueItem>(); AssetOutgoingPacketQueue = new Queue<LLQueItem>();
// Store the throttle multiplier for posterity.
throttleMultiplier = userSettings.ClientThrottleMultipler;
// Set up the throttle classes (min, max, current) in bits per second // Set up the throttle classes (min, max, current) in bits per second
ResendThrottle = new LLPacketThrottle(5000, 100000, 16000, userSettings.ClientThrottleMultipler); ResendThrottle = new LLPacketThrottle(5000, 100000, 16000, userSettings.ClientThrottleMultipler);
LandThrottle = new LLPacketThrottle(1000, 100000, 2000, userSettings.ClientThrottleMultipler); LandThrottle = new LLPacketThrottle(1000, 100000, 2000, userSettings.ClientThrottleMultipler);
@ -624,5 +628,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
return SendQueue.GetQueueArray(); return SendQueue.GetQueueArray();
} }
public float ThrottleMultiplier
{
get { return throttleMultiplier; }
}
} }
} }

View File

@ -25,11 +25,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
[Serializable]
public class Animation public class Animation
{ {
private UUID animID; private UUID animID;

View File

@ -25,11 +25,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
[Serializable]
public class AnimationSet public class AnimationSet
{ {
public static AvatarAnimations Animations = new AvatarAnimations(); public static AvatarAnimations Animations = new AvatarAnimations();

View File

@ -2048,17 +2048,22 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
public void SendTerseUpdateToClient(IClientAPI remoteClient) public void SendTerseUpdateToClient(IClientAPI remoteClient)
{ {
m_perfMonMS = System.Environment.TickCount; // If the client is inactive, it's getting its updates from another
// server.
if (remoteClient.IsActive)
{
m_perfMonMS = System.Environment.TickCount;
Vector3 pos = m_pos; Vector3 pos = m_pos;
Vector3 vel = Velocity; Vector3 vel = Velocity;
Quaternion rot = m_bodyRot; Quaternion rot = m_bodyRot;
pos.Z -= m_appearance.HipOffset; pos.Z -= m_appearance.HipOffset;
remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * (float)ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * (float)ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z),
new Vector3(vel.X, vel.Y, vel.Z), rot); new Vector3(vel.X, vel.Y, vel.Z), rot);
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
m_scene.AddAgentUpdates(1); m_scene.AddAgentUpdates(1);
}
} }
/// <summary> /// <summary>