From 08187cb59920f6def1e531f6bb62b3beb1b65a28 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 11 Sep 2015 20:40:10 +0100 Subject: inventory mess return to the state before divas cache issue --- .../Linden/Caps/FetchInventory2Module.cs | 20 +-- .../Linden/Caps/WebFetchInvDescModule.cs | 145 ++++++++++++++++----- 2 files changed, 122 insertions(+), 43 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs index 87d3d1c..e0a11cc 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs @@ -25,20 +25,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -using System.Collections; -using System.Reflection; -using log4net; -using Nini.Config; using Mono.Addins; +using Nini.Config; using OpenMetaverse; -using OpenSim.Framework; +using OpenSim.Capabilities.Handlers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using System; using Caps = OpenSim.Framework.Capabilities.Caps; -using OpenSim.Capabilities.Handlers; namespace OpenSim.Region.ClientStack.Linden { @@ -58,8 +54,6 @@ namespace OpenSim.Region.ClientStack.Linden private string m_fetchInventory2Url; - private FetchInventory2Handler m_fetchHandler; - #region ISharedRegionModule Members public void Initialise(IConfigSource source) @@ -98,10 +92,6 @@ namespace OpenSim.Region.ClientStack.Linden m_inventoryService = m_scene.InventoryService; - // We'll reuse the same handler for all requests. - if (m_fetchInventory2Url == "localhost") - m_fetchHandler = new FetchInventory2Handler(m_inventoryService); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; } @@ -131,9 +121,11 @@ namespace OpenSim.Region.ClientStack.Linden { capUrl = "/CAPS/" + UUID.Random(); + FetchInventory2Handler fetchHandler = new FetchInventory2Handler(m_inventoryService, agentID); + IRequestHandler reqHandler = new RestStreamHandler( - "POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString()); + "POST", capUrl, fetchHandler.FetchInventoryRequest, capName, agentID.ToString()); caps.RegisterHandler(capName, reqHandler); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 5f3e66a..2a252e1 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -66,7 +66,26 @@ namespace OpenSim.Region.ClientStack.Linden private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; + /// + /// Control whether requests will be processed asynchronously. + /// + /// + /// Defaults to true. Can currently not be changed once a region has been added to the module. + /// + public bool ProcessQueuedRequestsAsync { get; private set; } + + /// + /// Number of inventory requests processed by this module. + /// + /// + /// It's the PollServiceRequestManager that actually sends completed requests back to the requester. + /// + public static int ProcessedRequestsCount { get; set; } + + private static Stat s_queuedRequestsStat; + private static Stat s_processedRequestsStat; + + public Scene Scene { get; private set; } private IInventoryService m_InventoryService; private ILibraryService m_LibraryService; @@ -76,7 +95,7 @@ namespace OpenSim.Region.ClientStack.Linden private string m_fetchInventoryDescendents2Url; private string m_webFetchInventoryDescendentsUrl; - private static WebFetchInvDescHandler m_webFetchHandler; + private static FetchInvDescHandler m_webFetchHandler; private static Thread[] m_workerThreads = null; @@ -85,6 +104,13 @@ namespace OpenSim.Region.ClientStack.Linden #region ISharedRegionModule Members + public WebFetchInvDescModule() : this(true) {} + + public WebFetchInvDescModule(bool processQueuedResultsAsync) + { + ProcessQueuedRequestsAsync = processQueuedResultsAsync; + } + public void Initialise(IConfigSource source) { IConfig config = source.Configs["ClientStack.LindenCaps"]; @@ -92,8 +118,9 @@ namespace OpenSim.Region.ClientStack.Linden return; m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty); - m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); +// m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); +// if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty) if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty) { m_Enabled = true; @@ -105,7 +132,7 @@ namespace OpenSim.Region.ClientStack.Linden if (!m_Enabled) return; - m_scene = s; + Scene = s; } public void RemoveRegion(Scene s) @@ -113,12 +140,23 @@ namespace OpenSim.Region.ClientStack.Linden if (!m_Enabled) return; - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + Scene.EventManager.OnRegisterCaps -= RegisterCaps; - foreach (Thread t in m_workerThreads) - Watchdog.AbortThread(t.ManagedThreadId); + StatsManager.DeregisterStat(s_processedRequestsStat); + StatsManager.DeregisterStat(s_queuedRequestsStat); + + if (ProcessQueuedRequestsAsync) + { + if (m_workerThreads != null) + { + foreach (Thread t in m_workerThreads) + Watchdog.AbortThread(t.ManagedThreadId); - m_scene = null; + m_workerThreads = null; + } + } + + Scene = null; } public void RegionLoaded(Scene s) @@ -126,19 +164,51 @@ namespace OpenSim.Region.ClientStack.Linden if (!m_Enabled) return; - m_InventoryService = m_scene.InventoryService; - m_LibraryService = m_scene.LibraryService; + if (s_processedRequestsStat == null) + s_processedRequestsStat = + new Stat( + "ProcessedFetchInventoryRequests", + "Number of processed fetch inventory requests", + "These have not necessarily yet been dispatched back to the requester.", + "", + "inventory", + "httpfetch", + StatType.Pull, + MeasuresOfInterest.AverageChangeOverTime, + stat => { stat.Value = ProcessedRequestsCount; }, + StatVerbosity.Debug); + + if (s_queuedRequestsStat == null) + s_queuedRequestsStat = + new Stat( + "QueuedFetchInventoryRequests", + "Number of fetch inventory requests queued for processing", + "", + "", + "inventory", + "httpfetch", + StatType.Pull, + MeasuresOfInterest.AverageChangeOverTime, + stat => { stat.Value = m_queue.Count; }, + StatVerbosity.Debug); + + StatsManager.RegisterStat(s_processedRequestsStat); + StatsManager.RegisterStat(s_queuedRequestsStat); + + m_InventoryService = Scene.InventoryService; + m_LibraryService = Scene.LibraryService; // We'll reuse the same handler for all requests. - m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); + m_webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, Scene); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; + Scene.EventManager.OnRegisterCaps += RegisterCaps; - if (m_workerThreads == null) + int nworkers = 2; // was 2 + if (ProcessQueuedRequestsAsync && m_workerThreads == null) { - m_workerThreads = new Thread[2]; + m_workerThreads = new Thread[nworkers]; - for (uint i = 0; i < 2; i++) + for (uint i = 0; i < nworkers; i++) { m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, String.Format("InventoryWorkerThread{0}", i), @@ -173,12 +243,12 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary responses = new Dictionary(); - private Scene m_scene; + private WebFetchInvDescModule m_module; - public PollServiceInventoryEventArgs(Scene scene, string url, UUID pId) : - base(null, url, null, null, null, pId, int.MaxValue) + public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : + base(null, url, null, null, null, pId, int.MaxValue) { - m_scene = scene; + m_module = module; HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; GetEvents = (x, y) => @@ -198,12 +268,7 @@ namespace OpenSim.Region.ClientStack.Linden Request = (x, y) => { - ScenePresence sp = m_scene.GetScenePresence(Id); - if (sp == null) - { - m_log.ErrorFormat("[INVENTORY]: Unable to find ScenePresence for {0}", Id); - return; - } + ScenePresence sp = m_module.Scene.GetScenePresence(Id); aPollRequest reqinfo = new aPollRequest(); reqinfo.thepoll = this; @@ -298,7 +363,13 @@ namespace OpenSim.Region.ClientStack.Linden requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); lock (responses) + { + if (responses.ContainsKey(requestID)) + m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); responses[requestID] = response; + } + + WebFetchInvDescModule.ProcessedRequestsCount++; } } @@ -322,7 +393,7 @@ namespace OpenSim.Region.ClientStack.Linden capUrl = "/CAPS/" + UUID.Random() + "/"; // Register this as a poll service - PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, capUrl, agentID); + PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(this, capUrl, agentID); args.Type = PollServiceEventArgs.EventType.Inventory; caps.RegisterPollHandler(capName, args); @@ -331,7 +402,7 @@ namespace OpenSim.Region.ClientStack.Linden else { capUrl = url; - IExternalCapsModule handler = m_scene.RequestModuleInterface(); + IExternalCapsModule handler = Scene.RequestModuleInterface(); if (handler != null) handler.RegisterExternalUserCapsHandler(agentID,caps,capName,capUrl); else @@ -360,10 +431,26 @@ namespace OpenSim.Region.ClientStack.Linden { Watchdog.UpdateThread(); - aPollRequest poolreq = m_queue.Dequeue(); + WaitProcessQueuedInventoryRequest(); + } + } + + public void WaitProcessQueuedInventoryRequest() + { + aPollRequest poolreq = m_queue.Dequeue(); - if (poolreq != null && poolreq.thepoll != null) + if (poolreq != null && poolreq.thepoll != null) + { + try + { poolreq.thepoll.Process(poolreq); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[INVENTORY]: Failed to process queued inventory request {0} for {1} in {2}. Exception {3}", + poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", Scene.Name, e); + } } } } -- cgit v1.1