aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs178
1 files changed, 99 insertions, 79 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 4f8e2cd..40a400f 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
428 /// <summary> 428 /// <summary>
429 /// delegate for sending a grid instant message asynchronously 429 /// delegate for sending a grid instant message asynchronously
430 /// </summary> 430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); 431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
432 432
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
434 { 434 {
@@ -442,118 +442,138 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
442 { 442 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
444 444
445 d.BeginInvoke(im, result, GridInstantMessageCompleted, d); 445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
446 } 446 }
447 447
448 /// <summary> 448 /// <summary>
449 /// Internal SendGridInstantMessage over XMLRPC method. 449 /// Recursive SendGridInstantMessage over XMLRPC method.
450 /// This is called from within a dedicated thread. 450 /// This is called from within a dedicated thread.
451 /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from
452 /// itself, prevRegionHandle will be the last region handle that we tried to send.
453 /// If the handles are the same, we look up the user's location using the grid.
454 /// If the handles are still the same, we end. The send failed.
451 /// </summary> 455 /// </summary>
452 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result) 456 /// <param name="prevRegionHandle">
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last
458 /// regionhandle tried
459 /// </param>
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
453 { 461 {
454 UUID toAgentID = new UUID(im.toAgentID); 462 UUID toAgentID = new UUID(im.toAgentID);
455 UUID regionID;
456 bool lookupAgent;
457 463
458 /* 464 PresenceInfo upd = null;
459 * Try to get what region the agent is in from the cache. 465
460 */ 466 bool lookupAgent = false;
467
461 lock (m_UserRegionMap) 468 lock (m_UserRegionMap)
462 { 469 {
463 lookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID); 470 if (m_UserRegionMap.ContainsKey(toAgentID))
471 {
472 upd = new PresenceInfo();
473 upd.RegionID = m_UserRegionMap[toAgentID];
474
475 // We need to compare the current regionhandle with the previous region handle
476 // or the recursive loop will never end because it will never try to lookup the agent again
477 if (prevRegionID == upd.RegionID)
478 {
479 lookupAgent = true;
480 }
481 }
482 else
483 {
484 lookupAgent = true;
485 }
464 } 486 }
487
465 488
466 while (true) 489 // Are we needing to look-up an agent?
490 if (lookupAgent)
467 { 491 {
468 492 // Non-cached user agent lookup.
469 /* 493 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
470 * If not in cache, try to find out what region the agent is in. 494 if (presences != null && presences.Length > 0)
471 * Also do this if we know the existing cache entry is bad.
472 */
473 if (lookupAgent)
474 { 495 {
475 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 496 foreach (PresenceInfo p in presences)
476
477 regionID = UUID.Zero;
478 if (presences != null)
479 { 497 {
480 foreach (PresenceInfo p in presences) 498 if (p.RegionID != UUID.Zero)
481 { 499 {
482 if (p.RegionID != UUID.Zero) 500 upd = p;
483 { 501 break;
484 regionID = p.RegionID;
485 break;
486 }
487 } 502 }
488 } 503 }
504 }
489 505
490 // If not found, message is undeliverable 506 if (upd != null)
491 if (regionID == UUID.Zero) 507 {
508 // check if we've tried this before..
509 // This is one way to end the recursive loop
510 //
511 if (upd.RegionID == prevRegionID)
492 { 512 {
493 break; 513 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
514 HandleUndeliveredMessage(im, result);
515 return;
494 } 516 }
495 } 517 }
496 518 else
497 /*
498 * Try to find out about region.
499 * If unable, message is undeliverable.
500 */
501 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
502 if (reginfo == null)
503 { 519 {
504 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID); 520 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
505 break; 521 HandleUndeliveredMessage(im, result);
522 return;
506 } 523 }
524 }
507 525
508 /* 526 if (upd != null)
509 * Try to send message to agent in the region. 527 {
510 */ 528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
511 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 529 upd.RegionID);
512 msgdata["region_handle"] = 0; 530 if (reginfo != null)
513 bool imresult = doIMSending(reginfo, msgdata);
514
515 /*
516 * If message delivery successful, save cache entry because we know it is good.
517 * Then tell caller message has been delivered and we are done.
518 */
519 if (imresult)
520 { 531 {
521 lock (m_UserRegionMap) 532 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
533 // Not actually used anymore, left in for compatibility
534 // Remove at next interface change
535 //
536 msgdata["region_handle"] = 0;
537 bool imresult = doIMSending(reginfo, msgdata);
538 if (imresult)
539 {
540 // IM delivery successful, so store the Agent's location in our local cache.
541 lock (m_UserRegionMap)
542 {
543 if (m_UserRegionMap.ContainsKey(toAgentID))
544 {
545 m_UserRegionMap[toAgentID] = upd.RegionID;
546 }
547 else
548 {
549 m_UserRegionMap.Add(toAgentID, upd.RegionID);
550 }
551 }
552 result(true);
553 }
554 else
522 { 555 {
523 m_UserRegionMap[toAgentID] = regionID; 556 // try again, but lookup user this time.
557 // Warning, this must call the Async version
558 // of this method or we'll be making thousands of threads
559 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
560 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
561
562 // This is recursive!!!!!
563 SendGridInstantMessageViaXMLRPCAsync(im, result,
564 upd.RegionID);
524 } 565 }
525 result(true);
526 return;
527 } 566 }
528 567 else
529 /*
530 * Message delivery failed.
531 * If we just looked up what region the agent is in, message is undeliverable.
532 */
533 if (lookupAgent)
534 { 568 {
535 break; 569 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
570 HandleUndeliveredMessage(im, result);
536 } 571 }
537
538 /*
539 * We used a cached entry that we now know is bad.
540 * Try again by searching the grid for the user.
541 */
542 lookupAgent = true;
543 } 572 }
544 573 else
545 /*
546 * Message is undeliverable for one reason or another.
547 * Remove possible bad entry from cache.
548 * Then inform caller that the message is undeliverable.
549 */
550 lock (m_UserRegionMap)
551 { 574 {
552 m_UserRegionMap.Remove(toAgentID); 575 HandleUndeliveredMessage(im, result);
553 } 576 }
554
555 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
556 HandleUndeliveredMessage(im, result);
557 } 577 }
558 578
559 /// <summary> 579 /// <summary>