diff options
author | Teravus Ovares | 2009-07-29 02:15:45 +0000 |
---|---|---|
committer | Teravus Ovares | 2009-07-29 02:15:45 +0000 |
commit | 032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35 (patch) | |
tree | 63d21eaa99b003b47f8eceb09e21b6c4f32ae4f7 /OpenSim/Region | |
parent | Add the missing block to the alert message (diff) | |
download | opensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.zip opensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.gz opensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.bz2 opensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.xz |
* 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.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs | 93 |
1 files changed, 80 insertions, 13 deletions
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 | |||
61 | 61 | ||
62 | private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); | 62 | private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); |
63 | 63 | ||
64 | private Dictionary<UUID, BlockingLLSDQueue> queues = new Dictionary<UUID, BlockingLLSDQueue>(); | 64 | private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); |
65 | private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>(); | 65 | private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>(); |
66 | private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); | 66 | private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); |
67 | 67 | ||
@@ -131,7 +131,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
131 | /// </summary> | 131 | /// </summary> |
132 | /// <param name="agentId"></param> | 132 | /// <param name="agentId"></param> |
133 | /// <returns></returns> | 133 | /// <returns></returns> |
134 | private BlockingLLSDQueue TryGetQueue(UUID agentId) | 134 | private Queue<OSD> TryGetQueue(UUID agentId) |
135 | { | 135 | { |
136 | lock (queues) | 136 | lock (queues) |
137 | { | 137 | { |
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
141 | "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", | 141 | "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", |
142 | agentId, m_scene.RegionInfo.RegionName); | 142 | agentId, m_scene.RegionInfo.RegionName); |
143 | 143 | ||
144 | queues[agentId] = new BlockingLLSDQueue(); | 144 | queues[agentId] = new Queue<OSD>(); |
145 | } | 145 | } |
146 | 146 | ||
147 | return queues[agentId]; | 147 | return queues[agentId]; |
@@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
153 | /// </summary> | 153 | /// </summary> |
154 | /// <param name="agentId"></param> | 154 | /// <param name="agentId"></param> |
155 | /// <returns></returns> | 155 | /// <returns></returns> |
156 | private BlockingLLSDQueue GetQueue(UUID agentId) | 156 | private Queue<OSD> GetQueue(UUID agentId) |
157 | { | 157 | { |
158 | lock (queues) | 158 | lock (queues) |
159 | { | 159 | { |
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
173 | //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); | 173 | //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); |
174 | try | 174 | try |
175 | { | 175 | { |
176 | BlockingLLSDQueue queue = GetQueue(avatarID); | 176 | Queue<OSD> queue = GetQueue(avatarID); |
177 | if (queue != null) | 177 | if (queue != null) |
178 | queue.Enqueue(ev); | 178 | queue.Enqueue(ev); |
179 | } | 179 | } |
@@ -203,7 +203,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
203 | m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); | 203 | m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); |
204 | 204 | ||
205 | int count = 0; | 205 | int count = 0; |
206 | while (queues.ContainsKey(AgentID) && queues[AgentID].Count() > 0 && count++ < 5) | 206 | while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) |
207 | { | 207 | { |
208 | Thread.Sleep(1000); | 208 | Thread.Sleep(1000); |
209 | } | 209 | } |
@@ -226,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
226 | foreach (UUID ky in removeitems) | 226 | foreach (UUID ky in removeitems) |
227 | { | 227 | { |
228 | m_AvatarQueueUUIDMapping.Remove(ky); | 228 | m_AvatarQueueUUIDMapping.Remove(ky); |
229 | MainServer.Instance.RemoveHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/"); | 229 | MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/"); |
230 | } | 230 | } |
231 | 231 | ||
232 | } | 232 | } |
@@ -315,8 +315,8 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
315 | })); | 315 | })); |
316 | 316 | ||
317 | // This will persist this beyond the expiry of the caps handlers | 317 | // This will persist this beyond the expiry of the caps handlers |
318 | MainServer.Instance.AddHTTPHandler( | 318 | MainServer.Instance.AddPollServiceHTTPHandler( |
319 | capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePath2); | 319 | capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePath2, new PollServiceEventArgs(HasEvents, GetEvents, NoEvents, agentID)); |
320 | 320 | ||
321 | Random rnd = new Random(Environment.TickCount); | 321 | Random rnd = new Random(Environment.TickCount); |
322 | lock (m_ids) | 322 | lock (m_ids) |
@@ -326,6 +326,73 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
326 | } | 326 | } |
327 | } | 327 | } |
328 | 328 | ||
329 | public bool HasEvents(UUID agentID) | ||
330 | { | ||
331 | Queue<OSD> queue = TryGetQueue(agentID); | ||
332 | if (queue.Count > 0) | ||
333 | return true; | ||
334 | else | ||
335 | return false; | ||
336 | |||
337 | } | ||
338 | |||
339 | public Hashtable GetEvents(UUID pAgentId, string request) | ||
340 | { | ||
341 | Queue<OSD> queue = TryGetQueue(pAgentId); | ||
342 | OSD element = queue.Dequeue(); // 15s timeout | ||
343 | |||
344 | |||
345 | |||
346 | int thisID = 0; | ||
347 | lock (m_ids) | ||
348 | thisID = m_ids[pAgentId]; | ||
349 | |||
350 | OSDArray array = new OSDArray(); | ||
351 | if (element == null) // didn't have an event in 15s | ||
352 | { | ||
353 | // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! | ||
354 | array.Add(EventQueueHelper.KeepAliveEvent()); | ||
355 | m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName); | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | array.Add(element); | ||
360 | while (queue.Count > 0) | ||
361 | { | ||
362 | array.Add(queue.Dequeue()); | ||
363 | thisID++; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | OSDMap events = new OSDMap(); | ||
368 | events.Add("events", array); | ||
369 | |||
370 | events.Add("id", new OSDInteger(thisID)); | ||
371 | lock (m_ids) | ||
372 | { | ||
373 | m_ids[pAgentId] = thisID + 1; | ||
374 | } | ||
375 | Hashtable responsedata = new Hashtable(); | ||
376 | responsedata["int_response_code"] = 200; | ||
377 | responsedata["content_type"] = "application/xml"; | ||
378 | responsedata["keepalive"] = false; | ||
379 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); | ||
380 | return responsedata; | ||
381 | //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); | ||
382 | } | ||
383 | |||
384 | public Hashtable NoEvents() | ||
385 | { | ||
386 | Hashtable responsedata = new Hashtable(); | ||
387 | responsedata["int_response_code"] = 502; | ||
388 | responsedata["content_type"] = "text/plain"; | ||
389 | responsedata["keepalive"] = false; | ||
390 | responsedata["str_response_string"] = "Upstream error: "; | ||
391 | responsedata["error_status_text"] = "Upstream error:"; | ||
392 | responsedata["http_protocol_version"] = "HTTP/1.0"; | ||
393 | return responsedata; | ||
394 | } | ||
395 | |||
329 | public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps) | 396 | public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps) |
330 | { | 397 | { |
331 | // TODO: this has to be redone to not busy-wait (and block the thread), | 398 | // TODO: this has to be redone to not busy-wait (and block the thread), |
@@ -341,8 +408,8 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
341 | // m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name); | 408 | // m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name); |
342 | // } | 409 | // } |
343 | 410 | ||
344 | BlockingLLSDQueue queue = TryGetQueue(agentID); | 411 | Queue<OSD> queue = TryGetQueue(agentID); |
345 | OSD element = queue.Dequeue(15000); // 15s timeout | 412 | OSD element = queue.Dequeue(); // 15s timeout |
346 | 413 | ||
347 | Hashtable responsedata = new Hashtable(); | 414 | Hashtable responsedata = new Hashtable(); |
348 | 415 | ||
@@ -381,9 +448,9 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue | |||
381 | else | 448 | else |
382 | { | 449 | { |
383 | array.Add(element); | 450 | array.Add(element); |
384 | while (queue.Count() > 0) | 451 | while (queue.Count > 0) |
385 | { | 452 | { |
386 | array.Add(queue.Dequeue(1)); | 453 | array.Add(queue.Dequeue()); |
387 | thisID++; | 454 | thisID++; |
388 | } | 455 | } |
389 | } | 456 | } |