Simplify friends caching by only doing this for root agents - no functions require caching for child agents.

This allows us to avoid unnecessary multiple calls to the friends service.
All friends functions originate from the root agent and only go to other root agents in existing code.
This also allows us to eliminate complex ref counting.
This commit is contained in:
Justin Clark-Casey (justincc)
2012-03-28 23:40:25 +01:00
parent 7aa0c05fba
commit d9f7b8549b
9 changed files with 31 additions and 55 deletions

View File

@@ -57,7 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public UUID PrincipalID;
public FriendInfo[] Friends;
public int Refcount;
public bool IsFriend(string friend)
{
@@ -255,6 +254,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnNewClient(IClientAPI client)
{
if (client.SceneAgent.IsChildAgent)
return;
client.OnInstantMessage += OnInstantMessage;
client.OnApproveFriendRequest += OnApproveFriendRequest;
client.OnDenyFriendRequest += OnDenyFriendRequest;
@@ -281,23 +283,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UUID agentID = client.AgentId;
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
{
friendsData.Refcount++;
return false;
}
else
{
friendsData = new UserFriendData();
friendsData.PrincipalID = agentID;
friendsData.Friends = GetFriendsFromService(client);
friendsData.Refcount = 1;
UserFriendData friendsData = new UserFriendData();
friendsData.PrincipalID = agentID;
friendsData.Friends = GetFriendsFromService(client);
m_Friends[agentID] = friendsData;
return true;
}
m_Friends[agentID] = friendsData;
}
return true;
}
private void OnClientClosed(UUID agentID, Scene scene)
@@ -307,23 +300,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
// do this for root agents closing out
StatusChange(agentID, false);
}
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
{
friendsData.Refcount--;
if (friendsData.Refcount <= 0)
m_Friends.Remove(agentID);
}
lock (m_Friends)
m_Friends.Remove(agentID);
}
}
private void OnMakeRootAgent(ScenePresence sp)
{
RecacheFriends(sp.ControllingClient);
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
// is on the critical path for transferring an avatar from one region to another.
CacheFriends(sp.ControllingClient);
}
private void OnClientLogin(IClientAPI client)
@@ -623,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
StoreFriendships(client.AgentId, friendID);
// Update the local cache.
RecacheFriends(client);
CacheFriends(client);
//
// Notify the friend
@@ -685,7 +672,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.SendAlertMessage("Unable to terminate friendship on this sim.");
// Update local cache
RecacheFriends(client);
CacheFriends(client);
client.SendTerminateFriend(exfriendID);
@@ -799,7 +786,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendClient.SendInstantMessage(im);
// Update the local cache
RecacheFriends(friendClient);
CacheFriends(friendClient);
// we're done
return true;
@@ -832,7 +819,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// the friend in this sim as root agent
friendClient.SendTerminateFriend(exfriendID);
// update local cache
RecacheFriends(friendClient);
CacheFriends(friendClient);
// we're done
return true;
}
@@ -933,19 +920,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return FriendsService.GetFriends(client.AgentId);
}
protected void RecacheFriends(IClientAPI client)
{
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
// is on the critical path for transferring an avatar from one region to another.
UUID agentID = client.AgentId;
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
friendsData.Friends = GetFriendsFromService(client);
}
}
/// <summary>
/// Are friends cached on this simulator for a particular user?
/// </summary>

View File

@@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
UUID agentID = client.AgentId;
// we do this only for the root agent
if (m_Friends[agentID].Refcount == 1)
if (!client.SceneAgent.IsChildAgent)
{
// We need to preload the user management cache with the names
// of foreign friends, just like we do with SOPs' creators
@@ -426,14 +426,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
RecacheFriends(agentClient);
CacheFriends(agentClient);
}
if (friendClient != null)
{
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
RecacheFriends(friendClient);
CacheFriends(friendClient);
}
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",