From 7e17f4296e91129990c15cdaaa1689922a57f9aa Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 24 Aug 2012 23:48:01 +0200 Subject: Fix background inventory loading (Viewer 3) so it won't lag out the sim --- .../Linden/Caps/WebFetchInvDescModule.cs | 152 ++++++++++++++------- 1 file changed, 103 insertions(+), 49 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 2359bd6..61387ed 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -27,12 +27,15 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Reflection; +using System.Threading; using log4net; using Nini.Config; using Mono.Addins; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -48,67 +51,49 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class WebFetchInvDescModule : INonSharedRegionModule { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IInventoryService m_InventoryService; private ILibraryService m_LibraryService; - private bool m_Enabled; + private WebFetchInvDescHandler m_webFetchHandler; - private string m_fetchInventoryDescendents2Url; - private string m_webFetchInventoryDescendentsUrl; + private ManualResetEvent m_ev = new ManualResetEvent(true); + private object m_lock = new object(); - private WebFetchInvDescHandler m_webFetchHandler; + private Dictionary m_capsDict = new Dictionary(); + private Dictionary m_requests = new Dictionary(); #region ISharedRegionModule Members public void Initialise(IConfigSource source) { - IConfig config = source.Configs["ClientStack.LindenCaps"]; - if (config == null) - return; - - m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty); - m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); - - if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty) - { - m_Enabled = true; - } } public void AddRegion(Scene s) { - if (!m_Enabled) - return; - m_scene = s; } public void RemoveRegion(Scene s) { - if (!m_Enabled) - return; - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; m_scene = null; } public void RegionLoaded(Scene s) { - if (!m_Enabled) - return; - m_InventoryService = m_scene.InventoryService; m_LibraryService = m_scene.LibraryService; // We'll reuse the same handler for all requests. - if (m_fetchInventoryDescendents2Url == "localhost" || m_webFetchInventoryDescendentsUrl == "localhost") - m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); + m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); m_scene.EventManager.OnRegisterCaps += RegisterCaps; + m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; } public void PostInitialise() @@ -128,41 +113,110 @@ namespace OpenSim.Region.ClientStack.Linden private void RegisterCaps(UUID agentID, Caps caps) { - if (m_webFetchInventoryDescendentsUrl != "") - RegisterFetchCap(agentID, caps, "WebFetchInventoryDescendents", m_webFetchInventoryDescendentsUrl); + string capUrl = "/CAPS/" + UUID.Random() + "/"; + + // Register this as a poll service + PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, agentID, 300000); + args.Type = PollServiceEventArgs.EventType.Inventory; + MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); + + string hostName = m_scene.RegionInfo.ExternalHostName; + uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; + string protocol = "http"; + + if (MainServer.Instance.UseSSL) + { + hostName = MainServer.Instance.SSLCommonName; + port = MainServer.Instance.SSLPort; + protocol = "https"; + } + caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); - if (m_fetchInventoryDescendents2Url != "") - RegisterFetchCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url); + m_capsDict[agentID] = capUrl; } - private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url) + private void DeregisterCaps(UUID agentID, Caps caps) { string capUrl; - if (url == "localhost") + if (m_capsDict.TryGetValue(agentID, out capUrl)) { - capUrl = "/CAPS/" + UUID.Random(); + MainServer.Instance.RemoveHTTPHandler("", capUrl); + m_capsDict.Remove(agentID); + } + } - IRequestHandler reqHandler - = new RestStreamHandler( - "POST", - capUrl, - m_webFetchHandler.FetchInventoryDescendentsRequest, - "FetchInventoryDescendents2", - agentID.ToString()); + public void HttpRequestHandler(UUID requestID, Hashtable request) + { + m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); + m_requests[requestID] = request; + } - caps.RegisterHandler(capName, reqHandler); + private bool HasEvents(UUID requestID, UUID sessionID) + { + lock (m_lock) + { + if (m_ev.WaitOne(0)) + { + m_ev.Reset(); + return true; + } + return false; } - else + } + + private Hashtable NoEvents(UUID requestID, UUID sessionID) + { + m_requests.Remove(requestID); + + Hashtable response = new Hashtable(); + + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + return response; + } + + private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) + { + Hashtable response = new Hashtable(); + + response["int_response_code"] = 500; + response["str_response_string"] = "Internal error"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + try { - capUrl = url; + Hashtable requestHash; + if (!m_requests.TryGetValue(requestID, out requestHash)) + { + lock (m_lock) + m_ev.Set(); + response["str_response_string"] = "Invalid request"; + return response; + } + + m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID); - caps.RegisterHandler(capName, capUrl); + string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null); + + m_requests.Remove(requestID); + + response["int_response_code"] = 200; + response["str_response_string"] = reply; + } + finally + { + lock (m_lock) + m_ev.Set(); } -// m_log.DebugFormat( -// "[WEB FETCH INV DESC MODULE]: Registered capability {0} at {1} in region {2} for {3}", -// capName, capUrl, m_scene.RegionInfo.RegionName, agentID); + return response; } } -} \ No newline at end of file +} -- cgit v1.1 From 6d48dbf8caaf862d096bf5a7d39fb1a28afe46b7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 24 Aug 2012 23:49:31 +0200 Subject: Remove debug spam --- OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 61387ed..b77ead3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -148,7 +148,7 @@ namespace OpenSim.Region.ClientStack.Linden public void HttpRequestHandler(UUID requestID, Hashtable request) { - m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); +// m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); m_requests[requestID] = request; } @@ -201,7 +201,7 @@ namespace OpenSim.Region.ClientStack.Linden return response; } - m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID); +// m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID); string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null); -- cgit v1.1 From b7737b7273e87fcd9159d81f9cdc784381f94a25 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 10 Sep 2012 01:20:34 +0100 Subject: webFetchInventory: change control event to simple flag, adjust locking --- .../Linden/Caps/WebFetchInvDescModule.cs | 43 ++++++++++++++++------ 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index b77ead3..2475b1f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -60,11 +60,12 @@ namespace OpenSim.Region.ClientStack.Linden private WebFetchInvDescHandler m_webFetchHandler; - private ManualResetEvent m_ev = new ManualResetEvent(true); +// private ManualResetEvent m_ev = new ManualResetEvent(true); private object m_lock = new object(); private Dictionary m_capsDict = new Dictionary(); private Dictionary m_requests = new Dictionary(); + bool m_busy = false; #region ISharedRegionModule Members @@ -116,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden string capUrl = "/CAPS/" + UUID.Random() + "/"; // Register this as a poll service + // absurd large timeout to tune later to make a bit less than viewer PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, agentID, 300000); + args.Type = PollServiceEventArgs.EventType.Inventory; MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); @@ -133,6 +136,8 @@ namespace OpenSim.Region.ClientStack.Linden caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); m_capsDict[agentID] = capUrl; + + m_busy = false; } private void DeregisterCaps(UUID agentID, Caps caps) @@ -149,25 +154,30 @@ namespace OpenSim.Region.ClientStack.Linden public void HttpRequestHandler(UUID requestID, Hashtable request) { // m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); - m_requests[requestID] = request; + lock(m_lock) + m_requests[requestID] = request; } private bool HasEvents(UUID requestID, UUID sessionID) { lock (m_lock) { +/* if (m_ev.WaitOne(0)) { m_ev.Reset(); return true; } return false; + */ + return !m_busy; } } private Hashtable NoEvents(UUID requestID, UUID sessionID) { - m_requests.Remove(requestID); + lock(m_lock) + m_requests.Remove(requestID); Hashtable response = new Hashtable(); @@ -177,11 +187,17 @@ namespace OpenSim.Region.ClientStack.Linden response["keepalive"] = false; response["reusecontext"] = false; + lock (m_lock) + m_busy = false; + return response; } private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) { + lock (m_lock) + m_busy = true; + Hashtable response = new Hashtable(); response["int_response_code"] = 500; @@ -192,20 +208,24 @@ namespace OpenSim.Region.ClientStack.Linden try { + Hashtable requestHash; - if (!m_requests.TryGetValue(requestID, out requestHash)) + lock (m_lock) { - lock (m_lock) - m_ev.Set(); - response["str_response_string"] = "Invalid request"; - return response; + if (!m_requests.TryGetValue(requestID, out requestHash)) + { + m_busy = false; + // m_ev.Set(); + response["str_response_string"] = "Invalid request"; + return response; + } + m_requests.Remove(requestID); } // m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID); string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null); - - m_requests.Remove(requestID); + response["int_response_code"] = 200; response["str_response_string"] = reply; @@ -213,7 +233,8 @@ namespace OpenSim.Region.ClientStack.Linden finally { lock (m_lock) - m_ev.Set(); +// m_ev.Set(); + m_busy = false; } return response; -- cgit v1.1 From 657428a43906c5e65ad56ed96fa05d82f84d6c9b Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 10 Sep 2012 01:52:02 +0200 Subject: Remove commented code --- .../Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 2475b1f..e996fe8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -60,7 +60,6 @@ namespace OpenSim.Region.ClientStack.Linden private WebFetchInvDescHandler m_webFetchHandler; -// private ManualResetEvent m_ev = new ManualResetEvent(true); private object m_lock = new object(); private Dictionary m_capsDict = new Dictionary(); @@ -162,14 +161,6 @@ namespace OpenSim.Region.ClientStack.Linden { lock (m_lock) { -/* - if (m_ev.WaitOne(0)) - { - m_ev.Reset(); - return true; - } - return false; - */ return !m_busy; } } @@ -215,7 +206,6 @@ namespace OpenSim.Region.ClientStack.Linden if (!m_requests.TryGetValue(requestID, out requestHash)) { m_busy = false; - // m_ev.Set(); response["str_response_string"] = "Invalid request"; return response; } @@ -233,7 +223,6 @@ namespace OpenSim.Region.ClientStack.Linden finally { lock (m_lock) -// m_ev.Set(); m_busy = false; } -- cgit v1.1 From a6753c14a509e11f65829b87070b440ac3b87c4a Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 11 Sep 2012 10:39:43 +0200 Subject: Revamp the v3 inventory sending. Uses threads and some nifty mechanics to leverage the Poll Service without blocking it's workers. --- .../Linden/Caps/WebFetchInvDescModule.cs | 198 ++++++++++++--------- 1 file changed, 117 insertions(+), 81 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index e996fe8..4908c2c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OpenSim.Capabilities.Handlers; +using OpenSim.Framework.Monitoring; namespace OpenSim.Region.ClientStack.Linden { @@ -58,13 +59,13 @@ namespace OpenSim.Region.ClientStack.Linden private IInventoryService m_InventoryService; private ILibraryService m_LibraryService; - private WebFetchInvDescHandler m_webFetchHandler; - - private object m_lock = new object(); + private static WebFetchInvDescHandler m_webFetchHandler; private Dictionary m_capsDict = new Dictionary(); - private Dictionary m_requests = new Dictionary(); - bool m_busy = false; + private static Thread[] m_workerThreads = null; + + private static OpenMetaverse.BlockingQueue m_queue = + new OpenMetaverse.BlockingQueue(); #region ISharedRegionModule Members @@ -94,6 +95,22 @@ namespace OpenSim.Region.ClientStack.Linden m_scene.EventManager.OnRegisterCaps += RegisterCaps; m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; + + if (m_workerThreads == null) + { + m_workerThreads = new Thread[2]; + + for (uint i = 0; i < 2; i++) + { + m_workerThreads[i] = Watchdog.StartThread(DoInventoryRequests, + String.Format("InventoryWorkerThread{0}", i), + ThreadPriority.Normal, + false, + true, + null, + int.MaxValue); + } + } } public void PostInitialise() @@ -111,13 +128,103 @@ namespace OpenSim.Region.ClientStack.Linden #endregion + ~WebFetchInvDescModule() + { + foreach (Thread t in m_workerThreads) + t.Abort(); + } + + private class PollServiceInventoryEventArgs : PollServiceEventArgs + { + private List requests = + new List(); + private Dictionary responses = + new Dictionary(); + + public PollServiceInventoryEventArgs(UUID pId) : + base(null, null, null, null, pId, 30000) + { + HasEvents = (x, y) => { return this.responses.ContainsKey(x); }; + GetEvents = (x, y, s) => + { + try + { + return this.responses[x]; + } + finally + { + responses.Remove(x); + } + }; + + Request = (x, y) => + { + y["RequestID"] = x.ToString(); + lock (this.requests) + this.requests.Add(y); + + m_queue.Enqueue(this); + }; + + NoEvents = (x, y) => + { + lock (this.requests) + { + Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString()); + requests.Remove(request); + } + + Hashtable response = new Hashtable(); + + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + return response; + }; + } + + public void Process() + { + Hashtable request = null; + + try + { + lock (this.requests) + { + request = requests[0]; + requests.RemoveAt(0); + } + } + catch + { + return; + } + + UUID requestID = new UUID(request["RequestID"].ToString()); + + Hashtable response = new Hashtable(); + + response["int_response_code"] = 200; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null); + + responses[requestID] = response; + } + } + private void RegisterCaps(UUID agentID, Caps caps) { string capUrl = "/CAPS/" + UUID.Random() + "/"; // Register this as a poll service // absurd large timeout to tune later to make a bit less than viewer - PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, agentID, 300000); + PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); args.Type = PollServiceEventArgs.EventType.Inventory; MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); @@ -135,8 +242,6 @@ namespace OpenSim.Region.ClientStack.Linden caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); m_capsDict[agentID] = capUrl; - - m_busy = false; } private void DeregisterCaps(UUID agentID, Caps caps) @@ -150,83 +255,14 @@ namespace OpenSim.Region.ClientStack.Linden } } - public void HttpRequestHandler(UUID requestID, Hashtable request) + private void DoInventoryRequests() { -// m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); - lock(m_lock) - m_requests[requestID] = request; - } - - private bool HasEvents(UUID requestID, UUID sessionID) - { - lock (m_lock) + while (true) { - return !m_busy; - } - } - - private Hashtable NoEvents(UUID requestID, UUID sessionID) - { - lock(m_lock) - m_requests.Remove(requestID); - - Hashtable response = new Hashtable(); - - response["int_response_code"] = 500; - response["str_response_string"] = "Script timeout"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; - - lock (m_lock) - m_busy = false; + PollServiceInventoryEventArgs args = m_queue.Dequeue(); - return response; - } - - private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) - { - lock (m_lock) - m_busy = true; - - Hashtable response = new Hashtable(); - - response["int_response_code"] = 500; - response["str_response_string"] = "Internal error"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; - - try - { - - Hashtable requestHash; - lock (m_lock) - { - if (!m_requests.TryGetValue(requestID, out requestHash)) - { - m_busy = false; - response["str_response_string"] = "Invalid request"; - return response; - } - m_requests.Remove(requestID); - } - -// m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID); - - string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null); - - - response["int_response_code"] = 200; - response["str_response_string"] = reply; - } - finally - { - lock (m_lock) - m_busy = false; + args.Process(); } - - return response; } } } -- cgit v1.1 From 68ece236a6cd8a2a9bc009287e43debdc6e9a79d Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 23 Sep 2012 23:55:28 +0200 Subject: Protect the responses map with a lock. Also remove ugly "this." type of member notation. --- .../Linden/Caps/WebFetchInvDescModule.cs | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 4908c2c..f76ea74 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -144,31 +144,34 @@ namespace OpenSim.Region.ClientStack.Linden public PollServiceInventoryEventArgs(UUID pId) : base(null, null, null, null, pId, 30000) { - HasEvents = (x, y) => { return this.responses.ContainsKey(x); }; + HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; GetEvents = (x, y, s) => { - try + lock (responses) { - return this.responses[x]; - } - finally - { - responses.Remove(x); + try + { + return responses[x]; + } + finally + { + responses.Remove(x); + } } }; Request = (x, y) => { y["RequestID"] = x.ToString(); - lock (this.requests) - this.requests.Add(y); + lock (requests) + requests.Add(y); m_queue.Enqueue(this); }; NoEvents = (x, y) => { - lock (this.requests) + lock (requests) { Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString()); requests.Remove(request); @@ -192,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden try { - lock (this.requests) + lock (requests) { request = requests[0]; requests.RemoveAt(0); @@ -214,7 +217,8 @@ namespace OpenSim.Region.ClientStack.Linden response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null); - responses[requestID] = response; + lock (responses) + responses[requestID] = response; } } -- cgit v1.1 From 4d681bfde617371bf14fb74da595887a33ec688b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 25 Sep 2012 03:59:19 +0100 Subject: do the same to webFecthInvDescModule --- .../Linden/Caps/WebFetchInvDescModule.cs | 58 ++++++++++------------ 1 file changed, 25 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index f76ea74..0f305b1 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -52,6 +52,13 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class WebFetchInvDescModule : INonSharedRegionModule { + struct aPollRequest + { + public PollServiceInventoryEventArgs thepoll; + public UUID reqID; + public Hashtable request; + } + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; @@ -64,8 +71,8 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; - private static OpenMetaverse.BlockingQueue m_queue = - new OpenMetaverse.BlockingQueue(); + private static OpenMetaverse.BlockingQueue m_queue = + new OpenMetaverse.BlockingQueue(); #region ISharedRegionModule Members @@ -131,18 +138,16 @@ namespace OpenSim.Region.ClientStack.Linden ~WebFetchInvDescModule() { foreach (Thread t in m_workerThreads) - t.Abort(); + Watchdog.AbortThread(t.ManagedThreadId); } private class PollServiceInventoryEventArgs : PollServiceEventArgs { - private List requests = - new List(); private Dictionary responses = new Dictionary(); public PollServiceInventoryEventArgs(UUID pId) : - base(null, null, null, null, pId, 30000) + base(null, null, null, null, pId, int.MaxValue) { HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; GetEvents = (x, y, s) => @@ -162,21 +167,23 @@ namespace OpenSim.Region.ClientStack.Linden Request = (x, y) => { - y["RequestID"] = x.ToString(); - lock (requests) - requests.Add(y); + aPollRequest reqinfo = new aPollRequest(); + reqinfo.thepoll = this; + reqinfo.reqID = x; + reqinfo.request = y; - m_queue.Enqueue(this); + m_queue.Enqueue(reqinfo); }; NoEvents = (x, y) => { +/* lock (requests) { Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString()); requests.Remove(request); } - +*/ Hashtable response = new Hashtable(); response["int_response_code"] = 500; @@ -189,24 +196,9 @@ namespace OpenSim.Region.ClientStack.Linden }; } - public void Process() + public void Process(aPollRequest requestinfo) { - Hashtable request = null; - - try - { - lock (requests) - { - request = requests[0]; - requests.RemoveAt(0); - } - } - catch - { - return; - } - - UUID requestID = new UUID(request["RequestID"].ToString()); + UUID requestID = requestinfo.reqID; Hashtable response = new Hashtable(); @@ -215,7 +207,8 @@ namespace OpenSim.Region.ClientStack.Linden response["keepalive"] = false; response["reusecontext"] = false; - response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null); + response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( + requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); lock (responses) responses[requestID] = response; @@ -226,8 +219,7 @@ namespace OpenSim.Region.ClientStack.Linden { string capUrl = "/CAPS/" + UUID.Random() + "/"; - // Register this as a poll service - // absurd large timeout to tune later to make a bit less than viewer + // Register this as a poll service PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); args.Type = PollServiceEventArgs.EventType.Inventory; @@ -263,9 +255,9 @@ namespace OpenSim.Region.ClientStack.Linden { while (true) { - PollServiceInventoryEventArgs args = m_queue.Dequeue(); + aPollRequest poolreq = m_queue.Dequeue(); - args.Process(); + poolreq.thepoll.Process(poolreq); } } } -- cgit v1.1 From 654dd289f263a4eef4f2aa70a1cb8d289ec7e04c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 26 Sep 2012 03:05:27 +0100 Subject: more changes to PollService --- OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 0f305b1..56070c6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -223,6 +223,7 @@ namespace OpenSim.Region.ClientStack.Linden PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); args.Type = PollServiceEventArgs.EventType.Inventory; + args.GetEventsNeedsRequest = false; MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); string hostName = m_scene.RegionInfo.ExternalHostName; -- cgit v1.1 From 7e3eba1064197024690c5b3cae4c2cf87319e48c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 26 Sep 2012 15:41:57 +0100 Subject: Seems nothing actually need the request body for getevents. so change control flag to false --- OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 56070c6..0f305b1 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -223,7 +223,6 @@ namespace OpenSim.Region.ClientStack.Linden PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); args.Type = PollServiceEventArgs.EventType.Inventory; - args.GetEventsNeedsRequest = false; MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); string hostName = m_scene.RegionInfo.ExternalHostName; -- cgit v1.1 From 617f1b9223375a2dda925e26c395901810d37697 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 26 Sep 2012 16:17:49 +0100 Subject: just remove the damm thing --- OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 0f305b1..0caeddf 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -150,7 +150,7 @@ namespace OpenSim.Region.ClientStack.Linden base(null, null, null, null, pId, int.MaxValue) { HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; - GetEvents = (x, y, s) => + GetEvents = (x, y) => { lock (responses) { -- cgit v1.1 From 598f891d703593bde4b96472b5d1b1ce6aaf4c74 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Feb 2013 04:03:32 +0100 Subject: Move SoubleQueu to Util. Change HTTP inv to prioritize COF. Determine COF for SP --- .../Linden/Caps/WebFetchInvDescModule.cs | 77 ++++++++++++++++++++-- 1 file changed, 70 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 04cd474..a823dd8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -39,10 +39,13 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Framework.Capabilities; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OpenSim.Capabilities.Handlers; using OpenSim.Framework.Monitoring; +using OpenMetaverse; +using OpenMetaverse.StructuredData; namespace OpenSim.Region.ClientStack.Linden { @@ -52,11 +55,13 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] public class WebFetchInvDescModule : INonSharedRegionModule { - struct aPollRequest + class aPollRequest { public PollServiceInventoryEventArgs thepoll; public UUID reqID; public Hashtable request; + public ScenePresence presence; + public List folders; } private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -71,8 +76,8 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; - private static OpenMetaverse.BlockingQueue m_queue = - new OpenMetaverse.BlockingQueue(); + private static DoubleQueue m_queue = + new DoubleQueue(); #region ISharedRegionModule Members @@ -143,12 +148,18 @@ namespace OpenSim.Region.ClientStack.Linden private class PollServiceInventoryEventArgs : PollServiceEventArgs { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Dictionary responses = new Dictionary(); - public PollServiceInventoryEventArgs(UUID pId) : + private Scene m_scene; + + public PollServiceInventoryEventArgs(Scene scene, UUID pId) : base(null, null, null, null, pId, int.MaxValue) { + m_scene = scene; + HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; GetEvents = (x, y) => { @@ -167,12 +178,64 @@ 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; + } + aPollRequest reqinfo = new aPollRequest(); reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; + reqinfo.presence = sp; + reqinfo.folders = new List(); + + // Decode the request here + string request = y["body"].ToString(); + + request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); + + request = request.Replace("fetch_folders0", "fetch_folders0"); + request = request.Replace("fetch_folders1", "fetch_folders1"); + + Hashtable hash = new Hashtable(); + try + { + hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + } + catch (LLSD.LLSDParseException e) + { + m_log.ErrorFormat("[INVENTORY]: Fetch error: {0}{1}" + e.Message, e.StackTrace); + m_log.Error("Request: " + request); + return; + } + + ArrayList foldersrequested = (ArrayList)hash["folders"]; + + bool highPriority = false; + + for (int i = 0; i < foldersrequested.Count; i++) + { + Hashtable inventoryhash = (Hashtable)foldersrequested[i]; + string folder = inventoryhash["folder_id"].ToString(); + UUID folderID; + if (UUID.TryParse(folder, out folderID)) + { + if (!reqinfo.folders.Contains(folderID)) + { + if (sp.COF != UUID.Zero && sp.COF == folderID) + highPriority = true; + reqinfo.folders.Add(folderID); + } + } + } - m_queue.Enqueue(reqinfo); + if (highPriority) + m_queue.EnqueueHigh(reqinfo); + else + m_queue.EnqueueLow(reqinfo); }; NoEvents = (x, y) => @@ -208,7 +271,7 @@ namespace OpenSim.Region.ClientStack.Linden response["reusecontext"] = false; response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( - requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); + requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); lock (responses) responses[requestID] = response; @@ -220,7 +283,7 @@ namespace OpenSim.Region.ClientStack.Linden string capUrl = "/CAPS/" + UUID.Random() + "/"; // Register this as a poll service - PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); + PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID); args.Type = PollServiceEventArgs.EventType.Inventory; MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); -- cgit v1.1 From 2ad72db0ecd834ca7071aa6038f209b64f79b868 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 3 Mar 2013 11:40:46 +0100 Subject: Make a viewer sent XML error prettier --- OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index a823dd8..707cc93 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -211,6 +211,10 @@ namespace OpenSim.Region.ClientStack.Linden m_log.Error("Request: " + request); return; } + catch (System.Xml.XmlException) + { + m_log.ErrorFormat("[INVENTORY]: XML Format error"); + } ArrayList foldersrequested = (ArrayList)hash["folders"]; -- cgit v1.1