Eliminated the UserManagement/UserManagementModule throttle thread. Made the other one generic, taking any continuation.

cpu-performance
Diva Canto 2013-07-16 17:04:32 -07:00
parent e0f0b88dec
commit 3fbd2c54bc
2 changed files with 151 additions and 192 deletions

View File

@ -42,7 +42,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.Framework namespace OpenSim.Region.CoreModules.Framework
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
public class GridServiceThrottleModule : ISharedRegionModule public class ServiceThrottleModule : ISharedRegionModule, IServiceThrottleModule
{ {
private static readonly ILog m_log = LogManager.GetLogger( private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
@ -52,12 +52,16 @@ namespace OpenSim.Region.CoreModules.Framework
//private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>(); //private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>();
// private OpenSim.Framework.DoubleQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.DoubleQueue<GridRegionRequest>(); // private OpenSim.Framework.DoubleQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.DoubleQueue<GridRegionRequest>();
private Queue<GridRegionRequest> m_RequestQueue = new Queue<GridRegionRequest>(); //private Queue<GridRegionRequest> m_RequestQueue = new Queue<GridRegionRequest>();
private Queue<Action> m_RequestQueue = new Queue<Action>();
#region ISharedRegionModule
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
m_timer = new System.Timers.Timer(); m_timer = new System.Timers.Timer();
m_timer.AutoReset = false; m_timer.AutoReset = false;
m_timer.Enabled = true;
m_timer.Interval = 15000; // 15 secs at first m_timer.Interval = 15000; // 15 secs at first
m_timer.Elapsed += ProcessQueue; m_timer.Elapsed += ProcessQueue;
m_timer.Start(); m_timer.Start();
@ -75,7 +79,9 @@ namespace OpenSim.Region.CoreModules.Framework
lock (m_scenes) lock (m_scenes)
{ {
m_scenes.Add(scene); m_scenes.Add(scene);
scene.RegisterModuleInterface<IServiceThrottleModule>(this);
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
} }
} }
@ -92,21 +98,6 @@ namespace OpenSim.Region.CoreModules.Framework
} }
} }
void OnNewClient(IClientAPI client)
{
client.OnRegionHandleRequest += OnRegionHandleRequest;
}
//void OnMakeRootAgent(ScenePresence obj)
//{
// lock (m_timer)
// {
// m_timer.Stop();
// m_timer.Interval = 1000;
// m_timer.Start();
// }
//}
public void PostInitialise() public void PostInitialise()
{ {
} }
@ -117,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Framework
public string Name public string Name
{ {
get { return "GridServiceThrottleModule"; } get { return "ServiceThrottleModule"; }
} }
public Type ReplaceableInterface public Type ReplaceableInterface
@ -125,9 +116,31 @@ namespace OpenSim.Region.CoreModules.Framework
get { return null; } get { return null; }
} }
#endregion ISharedRegionMOdule
#region Events
void OnNewClient(IClientAPI client)
{
client.OnRegionHandleRequest += OnRegionHandleRequest;
}
void OnMakeRootAgent(ScenePresence obj)
{
lock (m_timer)
{
if (!m_timer.Enabled)
{
m_timer.Interval = 1000;
m_timer.Enabled = true;
m_timer.Start();
}
}
}
public void OnRegionHandleRequest(IClientAPI client, UUID regionID) public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
{ {
//m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID); //m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
ulong handle = 0; ulong handle = 0;
if (IsLocalRegionHandle(regionID, out handle)) if (IsLocalRegionHandle(regionID, out handle))
{ {
@ -135,12 +148,65 @@ namespace OpenSim.Region.CoreModules.Framework
return; return;
} }
GridRegionRequest request = new GridRegionRequest(client, regionID); Action action = delegate
{
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
if (r != null && r.RegionHandle != 0)
client.SendRegionHandle(regionID, r.RegionHandle);
};
lock (m_RequestQueue) lock (m_RequestQueue)
m_RequestQueue.Enqueue(request); m_RequestQueue.Enqueue(action);
} }
#endregion Events
#region IServiceThrottleModule
public void Enqueue(Action continuation)
{
m_RequestQueue.Enqueue(continuation);
}
#endregion IServiceThrottleModule
#region Process Continuation Queue
private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
{
m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count);
while (m_RequestQueue.Count > 0)
{
Action continuation = null;
lock (m_RequestQueue)
continuation = m_RequestQueue.Dequeue();
if (continuation != null)
continuation();
}
if (AreThereRootAgents())
{
lock (m_timer)
{
m_timer.Interval = 1000; // 1 sec
m_timer.Enabled = true;
m_timer.Start();
}
}
else
lock (m_timer)
m_timer.Enabled = false;
}
#endregion Process Continuation Queue
#region Misc
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle) private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
{ {
regionHandle = 0; regionHandle = 0;
@ -157,65 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework
{ {
foreach (Scene s in m_scenes) foreach (Scene s in m_scenes)
{ {
if (s.GetRootAgentCount() > 0) foreach (ScenePresence sp in s.GetScenePresences())
return true; if (!sp.IsChildAgent)
return true;
} }
return false; return false;
} }
private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e) #endregion Misc
{
while (m_RequestQueue.Count > 0)
{
GridRegionRequest request = null;
lock (m_RequestQueue)
request = m_RequestQueue.Dequeue();
if (request != null)
{
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID);
if (r != null && r.RegionHandle != 0)
request.client.SendRegionHandle(request.regionID, r.RegionHandle);
}
}
if (AreThereRootAgents())
m_timer.Interval = 1000; // 1 sec
else
m_timer.Interval = 10000; // 10 secs
m_timer.Start();
}
private void ProcessQueue()
{
while (true)
{
Watchdog.UpdateThread();
GridRegionRequest request = m_RequestQueue.Dequeue();
if (request != null)
{
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID);
if (r != null && r.RegionHandle != 0)
request.client.SendRegionHandle(request.regionID, r.RegionHandle);
}
}
}
} }
class GridRegionRequest
{
public IClientAPI client;
public UUID regionID;
public GridRegionRequest(IClientAPI c, UUID r)
{
client = c;
regionID = r;
}
}
} }

View File

@ -56,16 +56,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
protected bool m_Enabled; protected bool m_Enabled;
protected List<Scene> m_Scenes = new List<Scene>(); protected List<Scene> m_Scenes = new List<Scene>();
protected IServiceThrottleModule m_ServiceThrottle;
// The cache // The cache
protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
// Throttle the name requests
//private OpenSim.Framework.BlockingQueue<NameRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<NameRequest>();
//private OpenSim.Framework.DoubleQueue<NameRequest> m_RequestQueue = new OpenSim.Framework.DoubleQueue<NameRequest>();
private Queue<NameRequest> m_RequestQueue = new Queue<NameRequest>();
private System.Timers.Timer m_timer;
#region ISharedRegionModule #region ISharedRegionModule
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
@ -118,6 +112,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public void RegionLoaded(Scene s) public void RegionLoaded(Scene s)
{ {
if (m_Enabled && m_ServiceThrottle == null)
m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>();
} }
public void PostInitialise() public void PostInitialise()
@ -157,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
} }
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", // "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
@ -165,12 +161,33 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
{ {
remote_client.SendNameReply(uuid, "Mr", "OpenSim"); client.SendNameReply(uuid, "Mr", "OpenSim");
} }
else else
{ {
NameRequest request = new NameRequest(remote_client, uuid); string[] names = new string[2];
m_RequestQueue.Enqueue(request); if (TryGetUserNamesFromCache(uuid, names))
{
client.SendNameReply(uuid, names[0], names[1]);
return;
}
// Not found in cache, get it from services
m_ServiceThrottle.Enqueue(delegate
{
m_log.DebugFormat("[YYY]: Name request {0}", uuid);
bool foundRealName = TryGetUserNamesFromServices(uuid, names);
if (names.Length == 2)
{
if (!foundRealName)
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, client.Name);
else
m_log.DebugFormat("[YYY]: Found user {0} {1} for uuid {2}", names[0], names[1], uuid);
client.SendNameReply(uuid, names[0], names[1]);
}
});
} }
} }
@ -286,15 +303,27 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
} }
/// <summary> /// <summary>
/// Try to get the names bound to the given uuid. ///
/// </summary> /// </summary>
/// <returns>True if the name was found, false if not.</returns> /// <param name="uuid"></param>
/// <param name='uuid'></param> /// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param>
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param> /// <returns></returns>
private bool TryGetUserNames(UUID uuid, out string[] names) private bool TryGetUserNames(UUID uuid, string[] names)
{ {
names = new string[2]; if (names == null)
names = new string[2];
if (TryGetUserNamesFromCache(uuid, names))
return true;
if (TryGetUserNamesFromServices(uuid, names))
return true;
return false;
}
private bool TryGetUserNamesFromCache(UUID uuid, string[] names)
{
lock (m_UserCache) lock (m_UserCache)
{ {
if (m_UserCache.ContainsKey(uuid)) if (m_UserCache.ContainsKey(uuid))
@ -306,6 +335,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
} }
} }
return false;
}
/// <summary>
/// Try to get the names bound to the given uuid, from the services.
/// </summary>
/// <returns>True if the name was found, false if not.</returns>
/// <param name='uuid'></param>
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
private bool TryGetUserNamesFromServices(UUID uuid, string[] names)
{
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
if (account != null) if (account != null)
@ -390,18 +430,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public string GetUserName(UUID uuid) public string GetUserName(UUID uuid)
{ {
string[] names; string[] names = new string[2];
TryGetUserNames(uuid, out names); TryGetUserNames(uuid, names);
if (names.Length == 2) return names[0] + " " + names[1];
{
string firstname = names[0];
string lastname = names[1];
return firstname + " " + lastname;
}
return "(hippos)";
} }
public string GetUserHomeURL(UUID userID) public string GetUserHomeURL(UUID userID)
@ -601,19 +634,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
protected void Init() protected void Init()
{ {
RegisterConsoleCmds(); RegisterConsoleCmds();
//Watchdog.StartThread(
// ProcessQueue,
// "NameRequestThread",
// ThreadPriority.BelowNormal,
// true,
// false);
m_timer = new System.Timers.Timer();
m_timer.AutoReset = false;
m_timer.Interval = 15000; // 15 secs at first
m_timer.Elapsed += ProcessQueue;
m_timer.Start();
} }
protected void RegisterConsoleCmds() protected void RegisterConsoleCmds()
@ -683,83 +703,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
MainConsole.Instance.Output(cdt.ToString()); MainConsole.Instance.Output(cdt.ToString());
} }
private void ProcessQueue()
{
while (true)
{
Watchdog.UpdateThread();
NameRequest request = m_RequestQueue.Dequeue();
if (request != null)
{
string[] names;
bool foundRealName = TryGetUserNames(request.uuid, out names);
if (names.Length == 2)
{
if (!foundRealName)
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name);
request.client.SendNameReply(request.uuid, names[0], names[1]);
}
}
}
}
private bool AreThereRootAgents()
{
foreach (Scene s in m_Scenes)
{
if (s.GetRootAgentCount() > 0)
return true;
}
return false;
}
private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
{
while (m_RequestQueue.Count > 0)
{
NameRequest request = null;
lock (m_RequestQueue)
request = m_RequestQueue.Dequeue();
if (request != null)
{
string[] names;
bool foundRealName = TryGetUserNames(request.uuid, out names);
if (names.Length == 2)
{
if (!foundRealName)
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name);
request.client.SendNameReply(request.uuid, names[0], names[1]);
}
}
}
if (AreThereRootAgents())
m_timer.Interval = 1000; // 1 sec
else
m_timer.Interval = 10000; // 10 secs
m_timer.Start();
}
}
class NameRequest
{
public IClientAPI client;
public UUID uuid;
public NameRequest(IClientAPI c, UUID n)
{
client = c;
uuid = n;
}
} }
} }