From 032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 29 Jul 2009 02:15:45 +0000 Subject: * Adds the ability to have a thread efficient long poll service (such as the eventqueue) * If this doesn't melt the Http Server, this will significantly reduce the number of threads in use on regions with many users. * Adds AddPollServiceHTTPHandler, and RemovePollServiceHTTPHandler to BaseHttpServer * Generic enough to be used for many long poll services, not only the EventQueue. --- .../Framework/EventQueue/EventQueueGetModule.cs | 93 +++++++++++++++++++--- 1 file changed, 80 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs index 81ea267..81b47be 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue private Dictionary m_ids = new Dictionary(); - private Dictionary queues = new Dictionary(); + private Dictionary> queues = new Dictionary>(); private Dictionary m_QueueUUIDAvatarMapping = new Dictionary(); private Dictionary m_AvatarQueueUUIDMapping = new Dictionary(); @@ -131,7 +131,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue /// /// /// - private BlockingLLSDQueue TryGetQueue(UUID agentId) + private Queue TryGetQueue(UUID agentId) { lock (queues) { @@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName); - queues[agentId] = new BlockingLLSDQueue(); + queues[agentId] = new Queue(); } return queues[agentId]; @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue /// /// /// - private BlockingLLSDQueue GetQueue(UUID agentId) + private Queue GetQueue(UUID agentId) { lock (queues) { @@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); try { - BlockingLLSDQueue queue = GetQueue(avatarID); + Queue queue = GetQueue(avatarID); if (queue != null) queue.Enqueue(ev); } @@ -203,7 +203,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); int count = 0; - while (queues.ContainsKey(AgentID) && queues[AgentID].Count() > 0 && count++ < 5) + while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) { Thread.Sleep(1000); } @@ -226,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue foreach (UUID ky in removeitems) { m_AvatarQueueUUIDMapping.Remove(ky); - MainServer.Instance.RemoveHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/"); + MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/"); } } @@ -315,8 +315,8 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue })); // This will persist this beyond the expiry of the caps handlers - MainServer.Instance.AddHTTPHandler( - capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePath2); + MainServer.Instance.AddPollServiceHTTPHandler( + capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePath2, new PollServiceEventArgs(HasEvents, GetEvents, NoEvents, agentID)); Random rnd = new Random(Environment.TickCount); lock (m_ids) @@ -326,6 +326,73 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue } } + public bool HasEvents(UUID agentID) + { + Queue queue = TryGetQueue(agentID); + if (queue.Count > 0) + return true; + else + return false; + + } + + public Hashtable GetEvents(UUID pAgentId, string request) + { + Queue queue = TryGetQueue(pAgentId); + OSD element = queue.Dequeue(); // 15s timeout + + + + int thisID = 0; + lock (m_ids) + thisID = m_ids[pAgentId]; + + OSDArray array = new OSDArray(); + if (element == null) // didn't have an event in 15s + { + // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! + array.Add(EventQueueHelper.KeepAliveEvent()); + m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName); + } + else + { + array.Add(element); + while (queue.Count > 0) + { + array.Add(queue.Dequeue()); + thisID++; + } + } + + OSDMap events = new OSDMap(); + events.Add("events", array); + + events.Add("id", new OSDInteger(thisID)); + lock (m_ids) + { + m_ids[pAgentId] = thisID + 1; + } + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 200; + responsedata["content_type"] = "application/xml"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); + return responsedata; + //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); + } + + public Hashtable NoEvents() + { + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 502; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Upstream error: "; + responsedata["error_status_text"] = "Upstream error:"; + responsedata["http_protocol_version"] = "HTTP/1.0"; + return responsedata; + } + public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps) { // TODO: this has to be redone to not busy-wait (and block the thread), @@ -341,8 +408,8 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue // m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name); // } - BlockingLLSDQueue queue = TryGetQueue(agentID); - OSD element = queue.Dequeue(15000); // 15s timeout + Queue queue = TryGetQueue(agentID); + OSD element = queue.Dequeue(); // 15s timeout Hashtable responsedata = new Hashtable(); @@ -381,9 +448,9 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue else { array.Add(element); - while (queue.Count() > 0) + while (queue.Count > 0) { - array.Add(queue.Dequeue(1)); + array.Add(queue.Dequeue()); thisID++; } } -- cgit v1.1