From ee4abb681e6cab29b4f7f95dd35c3810223771c9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 20 Oct 2012 02:02:13 +0100 Subject: [PATCH] Improve efficiency of friends notification by only make one PresenceService call for all friends rather than one for each friend. However, large groups could still take a very long time since we still need to message each avatar on different simulators. --- .../Avatar/Friends/FriendsModule.cs | 53 +++++++++---------- .../Connectors/Friends/FriendsSimConnector.cs | 4 +- .../HypergridService/HGFriendsService.cs | 2 +- .../HypergridService/UserAgentService.cs | 2 +- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 11db18a068..f1903c3e27 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Threading; using log4net; @@ -495,42 +496,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected virtual void StatusNotify(List friendList, UUID userID, bool online) { - foreach (FriendInfo friend in friendList) + List friendStringIds = friendList.ConvertAll(friend => friend.Friend); + List remoteFriendStringIds = new List(); + foreach (string friendStringId in friendStringIds) { - UUID friendID; - if (UUID.TryParse(friend.Friend, out friendID)) + UUID friendUuid; + if (UUID.TryParse(friendStringId, out friendUuid)) { - // Try local - if (LocalStatusNotification(userID, friendID, online)) + if (LocalStatusNotification(userID, friendUuid, online)) continue; - // The friend is not here [as root]. Let's forward. - PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); - if (friendSessions != null && friendSessions.Length > 0) - { - PresenceInfo friendSession = null; - foreach (PresenceInfo pinfo in friendSessions) - { - if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad - { - friendSession = pinfo; - break; - } - } - - if (friendSession != null) - { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); - m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); - } - } - - // Friend is not online. Ignore. + remoteFriendStringIds.Add(friendStringId); } else { - m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); + m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friendStringId); + } + } + + // We do this regrouping so that we can efficiently send a single request rather than one for each + // friend in what may be a very large friends list. + PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray()); + + foreach (PresenceInfo friendSession in friendSessions) + { + // let's guard against sessions-gone-bad + if (friendSession.RegionID != UUID.Zero) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); + m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online); } } } diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs index e235733734..6d5ce4be42 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs @@ -128,7 +128,7 @@ namespace OpenSim.Services.Connectors.Friends return Call(region, sendData); } - public bool StatusNotify(GridRegion region, UUID userID, UUID friendID, bool online) + public bool StatusNotify(GridRegion region, UUID userID, string friendID, bool online) { Dictionary sendData = new Dictionary(); //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); @@ -136,7 +136,7 @@ namespace OpenSim.Services.Connectors.Friends sendData["METHOD"] = "status"; sendData["FromID"] = userID.ToString(); - sendData["ToID"] = friendID.ToString(); + sendData["ToID"] = friendID; sendData["Online"] = online.ToString(); return Call(region, sendData); diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs index 98423d765c..a8bcfb2fa8 100644 --- a/OpenSim/Services/HypergridService/HGFriendsService.cs +++ b/OpenSim/Services/HypergridService/HGFriendsService.cs @@ -397,7 +397,7 @@ namespace OpenSim.Services.HypergridService if (region != null) { m_log.DebugFormat("[HGFRIENDS SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline")); - m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID, online); + m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID.ToString(), online); } } } diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 49c7f89598..45d1dafbca 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -436,7 +436,7 @@ namespace OpenSim.Services.HypergridService if (region != null) { m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline")); - m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID, online); + m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID.ToString(), online); } } }