From da2b23f18d232230ac4d967f8d3b256aebd4741e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 20 Oct 2012 02:02:13 +0100 Subject: 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. --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 53 ++++++++++------------ 1 file changed, 24 insertions(+), 29 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 11db18a..f1903c3 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); } } } -- cgit v1.1