aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorTeravus Ovares2009-07-29 02:15:45 +0000
committerTeravus Ovares2009-07-29 02:15:45 +0000
commit032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35 (patch)
tree63d21eaa99b003b47f8eceb09e21b6c4f32ae4f7 /OpenSim/Region
parentAdd the missing block to the alert message (diff)
downloadopensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.zip
opensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.gz
opensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.bz2
opensim-SC_OLD-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.cs93
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 }