aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs362
1 files changed, 220 insertions, 142 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 7d73b3e..5c721d4 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -39,6 +39,7 @@ using OpenMetaverse.Messages.Linden;
39using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
40using OpenMetaverse.StructuredData; 40using OpenMetaverse.StructuredData;
41using OpenSim.Framework; 41using OpenSim.Framework;
42using OpenSim.Framework.Console;
42using OpenSim.Framework.Servers; 43using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer; 44using OpenSim.Framework.Servers.HttpServer;
44using OpenSim.Region.Framework.Interfaces; 45using OpenSim.Region.Framework.Interfaces;
@@ -58,9 +59,15 @@ namespace OpenSim.Region.ClientStack.Linden
58 public class EventQueueGetModule : IEventQueue, IRegionModule 59 public class EventQueueGetModule : IEventQueue, IRegionModule
59 { 60 {
60 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61 protected Scene m_scene = null; 62
63 /// <value>
64 /// Debug level.
65 /// </value>
66 public int DebugLevel { get; set; }
67
68 protected Scene m_scene;
62 private IConfigSource m_gConfig; 69 private IConfigSource m_gConfig;
63 bool enabledYN = false; 70 bool enabledYN;
64 71
65 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 72 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
66 73
@@ -97,6 +104,15 @@ namespace OpenSim.Region.ClientStack.Linden
97 scene.EventManager.OnClientClosed += ClientClosed; 104 scene.EventManager.OnClientClosed += ClientClosed;
98 scene.EventManager.OnMakeChildAgent += MakeChildAgent; 105 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
99 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 106 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
107
108 MainConsole.Instance.Commands.AddCommand(
109 "event queue",
110 false,
111 "debug eq",
112 "debug eq [0|1]",
113 "debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
114 + "debug eq 1 will turn off event queue debugging.",
115 HandleDebugEq);
100 } 116 }
101 else 117 else
102 { 118 {
@@ -128,6 +144,22 @@ namespace OpenSim.Region.ClientStack.Linden
128 } 144 }
129 #endregion 145 #endregion
130 146
147 protected void HandleDebugEq(string module, string[] args)
148 {
149 int debugLevel;
150
151 if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
152 {
153 MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]");
154 }
155 else
156 {
157 DebugLevel = debugLevel;
158 MainConsole.Instance.OutputFormat(
159 "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
160 }
161 }
162
131 /// <summary> 163 /// <summary>
132 /// Always returns a valid queue 164 /// Always returns a valid queue
133 /// </summary> 165 /// </summary>
@@ -314,16 +346,22 @@ namespace OpenSim.Region.ClientStack.Linden
314 } 346 }
315 347
316 // Register this as a caps handler 348 // Register this as a caps handler
349 // FIXME: Confusingly, we need to register separate as a capability so that the client is told about
350 // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
351 // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
352 // really it should be possible to directly register the poll handler as a capability.
317 caps.RegisterHandler("EventQueueGet", 353 caps.RegisterHandler("EventQueueGet",
318 new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", 354 new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
319 delegate(Hashtable m_dhttpMethod) 355// delegate(Hashtable m_dhttpMethod)
320 { 356// {
321 return ProcessQueue(m_dhttpMethod, agentID, caps); 357// return ProcessQueue(m_dhttpMethod, agentID, caps);
322 })); 358// }));
323 359
324 // This will persist this beyond the expiry of the caps handlers 360 // This will persist this beyond the expiry of the caps handlers
325 MainServer.Instance.AddPollServiceHTTPHandler( 361 MainServer.Instance.AddPollServiceHTTPHandler(
326 capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); 362 capsBase + EventQueueGetUUID.ToString() + "/",
363 EventQueuePoll,
364 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
327 365
328 Random rnd = new Random(Environment.TickCount); 366 Random rnd = new Random(Environment.TickCount);
329 lock (m_ids) 367 lock (m_ids)
@@ -348,6 +386,8 @@ namespace OpenSim.Region.ClientStack.Linden
348 386
349 public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) 387 public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
350 { 388 {
389// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
390
351 Queue<OSD> queue = TryGetQueue(pAgentId); 391 Queue<OSD> queue = TryGetQueue(pAgentId);
352 OSD element; 392 OSD element;
353 lock (queue) 393 lock (queue)
@@ -370,12 +410,31 @@ namespace OpenSim.Region.ClientStack.Linden
370 } 410 }
371 else 411 else
372 { 412 {
413 if (DebugLevel > 0 && element is OSDMap)
414 {
415 OSDMap ev = (OSDMap)element;
416 m_log.DebugFormat(
417 "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
418 ev["message"], m_scene.GetScenePresence(pAgentId).Name);
419 }
420
373 array.Add(element); 421 array.Add(element);
422
374 lock (queue) 423 lock (queue)
375 { 424 {
376 while (queue.Count > 0) 425 while (queue.Count > 0)
377 { 426 {
378 array.Add(queue.Dequeue()); 427 element = queue.Dequeue();
428
429 if (DebugLevel > 0 && element is OSDMap)
430 {
431 OSDMap ev = (OSDMap)element;
432 m_log.DebugFormat(
433 "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
434 ev["message"], m_scene.GetScenePresence(pAgentId).Name);
435 }
436
437 array.Add(element);
379 thisID++; 438 thisID++;
380 } 439 }
381 } 440 }
@@ -412,148 +471,166 @@ namespace OpenSim.Region.ClientStack.Linden
412 return responsedata; 471 return responsedata;
413 } 472 }
414 473
415 public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps) 474// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
416 { 475// {
417 // TODO: this has to be redone to not busy-wait (and block the thread), 476// // TODO: this has to be redone to not busy-wait (and block the thread),
418 // TODO: as soon as we have a non-blocking way to handle HTTP-requests. 477// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
419 478//
420// if (m_log.IsDebugEnabled) 479//// if (m_log.IsDebugEnabled)
421// { 480//// {
422// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ "; 481//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
423// foreach (object key in request.Keys) 482//// foreach (object key in request.Keys)
483//// {
484//// debug += key.ToString() + "=" + request[key].ToString() + " ";
485//// }
486//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
487//// }
488//
489// Queue<OSD> queue = TryGetQueue(agentID);
490// OSD element;
491//
492// lock (queue)
493// element = queue.Dequeue(); // 15s timeout
494//
495// Hashtable responsedata = new Hashtable();
496//
497// int thisID = 0;
498// lock (m_ids)
499// thisID = m_ids[agentID];
500//
501// if (element == null)
502// {
503// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
504// if (thisID == -1) // close-request
424// { 505// {
425// debug += key.ToString() + "=" + request[key].ToString() + " "; 506// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
507// responsedata["int_response_code"] = 404; //501; //410; //404;
508// responsedata["content_type"] = "text/plain";
509// responsedata["keepalive"] = false;
510// responsedata["str_response_string"] = "Closed EQG";
511// return responsedata;
426// } 512// }
427// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name); 513// responsedata["int_response_code"] = 502;
514// responsedata["content_type"] = "text/plain";
515// responsedata["keepalive"] = false;
516// responsedata["str_response_string"] = "Upstream error: ";
517// responsedata["error_status_text"] = "Upstream error:";
518// responsedata["http_protocol_version"] = "HTTP/1.0";
519// return responsedata;
428// } 520// }
429 521//
430 Queue<OSD> queue = TryGetQueue(agentID); 522// OSDArray array = new OSDArray();
431 OSD element; 523// if (element == null) // didn't have an event in 15s
432 524// {
433 lock (queue) 525// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
434 element = queue.Dequeue(); // 15s timeout 526// array.Add(EventQueueHelper.KeepAliveEvent());
435 527// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
436 Hashtable responsedata = new Hashtable(); 528// }
437 529// else
438 int thisID = 0; 530// {
439 lock (m_ids) 531// array.Add(element);
440 thisID = m_ids[agentID]; 532//
441 533// if (element is OSDMap)
442 if (element == null) 534// {
443 { 535// OSDMap ev = (OSDMap)element;
444 //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName); 536// m_log.DebugFormat(
445 if (thisID == -1) // close-request 537// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
446 { 538// ev["message"], m_scene.GetScenePresence(agentID).Name);
447 m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName); 539// }
448 responsedata["int_response_code"] = 404; //501; //410; //404; 540//
449 responsedata["content_type"] = "text/plain"; 541// lock (queue)
450 responsedata["keepalive"] = false; 542// {
451 responsedata["str_response_string"] = "Closed EQG"; 543// while (queue.Count > 0)
452 return responsedata; 544// {
453 } 545// element = queue.Dequeue();
454 responsedata["int_response_code"] = 502; 546//
455 responsedata["content_type"] = "text/plain"; 547// if (element is OSDMap)
456 responsedata["keepalive"] = false; 548// {
457 responsedata["str_response_string"] = "Upstream error: "; 549// OSDMap ev = (OSDMap)element;
458 responsedata["error_status_text"] = "Upstream error:"; 550// m_log.DebugFormat(
459 responsedata["http_protocol_version"] = "HTTP/1.0"; 551// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
460 return responsedata; 552// ev["message"], m_scene.GetScenePresence(agentID).Name);
461 } 553// }
462 554//
463 OSDArray array = new OSDArray(); 555// array.Add(element);
464 if (element == null) // didn't have an event in 15s 556// thisID++;
465 { 557// }
466 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! 558// }
467 array.Add(EventQueueHelper.KeepAliveEvent()); 559// }
468 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 560//
469 } 561// OSDMap events = new OSDMap();
470 else 562// events.Add("events", array);
471 { 563//
472 array.Add(element); 564// events.Add("id", new OSDInteger(thisID));
473 565// lock (m_ids)
474 lock (queue) 566// {
475 { 567// m_ids[agentID] = thisID + 1;
476 while (queue.Count > 0) 568// }
477 { 569//
478 array.Add(queue.Dequeue()); 570// responsedata["int_response_code"] = 200;
479 thisID++; 571// responsedata["content_type"] = "application/xml";
480 } 572// responsedata["keepalive"] = false;
481 } 573// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
482 } 574//
483 575// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
484 OSDMap events = new OSDMap(); 576//
485 events.Add("events", array); 577// return responsedata;
486 578// }
487 events.Add("id", new OSDInteger(thisID));
488 lock (m_ids)
489 {
490 m_ids[agentID] = thisID + 1;
491 }
492
493 responsedata["int_response_code"] = 200;
494 responsedata["content_type"] = "application/xml";
495 responsedata["keepalive"] = false;
496 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
497 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
498
499 return responsedata;
500 }
501 579
502 public Hashtable EventQueuePoll(Hashtable request) 580 public Hashtable EventQueuePoll(Hashtable request)
503 { 581 {
504 return new Hashtable(); 582 return new Hashtable();
505 } 583 }
506 584
507 public Hashtable EventQueuePath2(Hashtable request) 585// public Hashtable EventQueuePath2(Hashtable request)
508 { 586// {
509 string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/",""); 587// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
510 // pull off the last "/" in the path. 588// // pull off the last "/" in the path.
511 Hashtable responsedata = new Hashtable(); 589// Hashtable responsedata = new Hashtable();
512 capuuid = capuuid.Substring(0, capuuid.Length - 1); 590// capuuid = capuuid.Substring(0, capuuid.Length - 1);
513 capuuid = capuuid.Replace("/CAPS/EQG/", ""); 591// capuuid = capuuid.Replace("/CAPS/EQG/", "");
514 UUID AvatarID = UUID.Zero; 592// UUID AvatarID = UUID.Zero;
515 UUID capUUID = UUID.Zero; 593// UUID capUUID = UUID.Zero;
516 594//
517 // parse the path and search for the avatar with it registered 595// // parse the path and search for the avatar with it registered
518 if (UUID.TryParse(capuuid, out capUUID)) 596// if (UUID.TryParse(capuuid, out capUUID))
519 { 597// {
520 lock (m_QueueUUIDAvatarMapping) 598// lock (m_QueueUUIDAvatarMapping)
521 { 599// {
522 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID)) 600// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
523 { 601// {
524 AvatarID = m_QueueUUIDAvatarMapping[capUUID]; 602// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
525 } 603// }
526 } 604// }
527 605//
528 if (AvatarID != UUID.Zero) 606// if (AvatarID != UUID.Zero)
529 { 607// {
530 return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID)); 608// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
531 } 609// }
532 else 610// else
533 { 611// {
534 responsedata["int_response_code"] = 404; 612// responsedata["int_response_code"] = 404;
535 responsedata["content_type"] = "text/plain"; 613// responsedata["content_type"] = "text/plain";
536 responsedata["keepalive"] = false; 614// responsedata["keepalive"] = false;
537 responsedata["str_response_string"] = "Not Found"; 615// responsedata["str_response_string"] = "Not Found";
538 responsedata["error_status_text"] = "Not Found"; 616// responsedata["error_status_text"] = "Not Found";
539 responsedata["http_protocol_version"] = "HTTP/1.0"; 617// responsedata["http_protocol_version"] = "HTTP/1.0";
540 return responsedata; 618// return responsedata;
541 // return 404 619// // return 404
542 } 620// }
543 } 621// }
544 else 622// else
545 { 623// {
546 responsedata["int_response_code"] = 404; 624// responsedata["int_response_code"] = 404;
547 responsedata["content_type"] = "text/plain"; 625// responsedata["content_type"] = "text/plain";
548 responsedata["keepalive"] = false; 626// responsedata["keepalive"] = false;
549 responsedata["str_response_string"] = "Not Found"; 627// responsedata["str_response_string"] = "Not Found";
550 responsedata["error_status_text"] = "Not Found"; 628// responsedata["error_status_text"] = "Not Found";
551 responsedata["http_protocol_version"] = "HTTP/1.0"; 629// responsedata["http_protocol_version"] = "HTTP/1.0";
552 return responsedata; 630// return responsedata;
553 // return 404 631// // return 404
554 } 632// }
555 633// }
556 }
557 634
558 public OSD EventQueueFallBack(string path, OSD request, string endpoint) 635 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
559 { 636 {
@@ -717,6 +794,7 @@ namespace OpenSim.Region.ClientStack.Linden
717 OSD item = EventQueueHelper.GroupMembership(groupUpdate); 794 OSD item = EventQueueHelper.GroupMembership(groupUpdate);
718 Enqueue(item, avatarID); 795 Enqueue(item, avatarID);
719 } 796 }
797
720 public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID) 798 public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
721 { 799 {
722 OSD item = EventQueueHelper.PlacesQuery(groupUpdate); 800 OSD item = EventQueueHelper.PlacesQuery(groupUpdate);