From 9432f3c94d0b0345132e5ff9eaf966b96cf218c2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 16 Jul 2013 19:04:30 -0700 Subject: Improvements to the ServiceThrottleModule: added a category and an itemid to the interface, so that duplicate requests aren't enqueued more than once. --- .../ServiceThrottle/ServiceThrottleModule.cs | 35 ++++++++++++++++------ .../UserManagement/UserManagementModule.cs | 2 +- .../Framework/Interfaces/IServiceThrottleModule.cs | 10 ++++++- 3 files changed, 36 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs index a3ca6d6..1554b3e 100644 --- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs @@ -50,17 +50,15 @@ namespace OpenSim.Region.CoreModules.Framework private readonly List m_scenes = new List(); private System.Timers.Timer m_timer = new System.Timers.Timer(); - //private OpenSim.Framework.BlockingQueue m_RequestQueue = new OpenSim.Framework.BlockingQueue(); - // private OpenSim.Framework.DoubleQueue m_RequestQueue = new OpenSim.Framework.DoubleQueue(); - //private Queue m_RequestQueue = new Queue(); private Queue m_RequestQueue = new Queue(); + private Dictionary> m_Pending = new Dictionary>(); private int m_Interval; #region ISharedRegionModule public void Initialise(IConfigSource config) { - m_Interval = Util.GetConfigVarFromSections(config, "Interval", new string[] { "ServiceThrottle" }, 2000); + m_Interval = Util.GetConfigVarFromSections(config, "Interval", new string[] { "ServiceThrottle" }, 5000); m_timer = new System.Timers.Timer(); m_timer.AutoReset = false; @@ -159,18 +157,37 @@ namespace OpenSim.Region.CoreModules.Framework client.SendRegionHandle(regionID, r.RegionHandle); }; - lock (m_RequestQueue) - m_RequestQueue.Enqueue(action); - + Enqueue("region", regionID.ToString(), action); } #endregion Events #region IServiceThrottleModule - public void Enqueue(Action continuation) + public void Enqueue(string category, string itemid, Action continuation) { - m_RequestQueue.Enqueue(continuation); + lock (m_RequestQueue) + { + if (m_Pending.ContainsKey(category)) + { + if (m_Pending[category].Contains(itemid)) + // Don't enqueue, it's already pending + return; + } + else + m_Pending.Add(category, new List()); + + m_Pending[category].Add(itemid); + + m_RequestQueue.Enqueue(delegate + { + continuation(); + lock (m_RequestQueue) + { + m_Pending[category].Remove(itemid); + } + }); + } } #endregion IServiceThrottleModule diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index e8bdcc9..a91adfa 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } // Not found in cache, queue continuation - m_ServiceThrottle.Enqueue(delegate + m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate { //m_log.DebugFormat("[YYY]: Name request {0}", uuid); bool foundRealName = TryGetUserNames(uuid, names); diff --git a/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs index bb6a8b4..198256f 100644 --- a/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs @@ -5,7 +5,15 @@ namespace OpenSim.Region.Framework.Interfaces { public interface IServiceThrottleModule { - void Enqueue(Action continuation); + /// + /// Enqueue a continuation meant to get a resource from elsewhere. + /// As usual with CPS, caller beware: if that continuation is a never-ending computation, + /// the whole thread will be blocked, and no requests are processed + /// + /// Category of the resource (e.g. name, region) + /// The resource identifier + /// The continuation to be executed + void Enqueue(string category, string itemid, Action continuation); } } -- cgit v1.1