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.
0.7.4-extended
Justin Clark-Casey (justincc) 2012-10-20 02:02:13 +01:00
parent 9e3605d952
commit ee4abb681e
4 changed files with 28 additions and 33 deletions

View File

@ -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<FriendInfo> friendList, UUID userID, bool online)
{
foreach (FriendInfo friend in friendList)
List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend);
List<string> remoteFriendStringIds = new List<string>();
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);
}
}
}

View File

@ -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<string, object> sendData = new Dictionary<string, object>();
//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);

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}