Thanks, lulurun, for a patch that addresses inventory problems that occur

occasionally, but are fixed on restart (issue 1919).
This patch introduces the following changes:
1. when a user teleports out of Region A, remove that user's profile
from the Region A user profile cache
2. when a user crosses between regions out of Region A, remove that
user's profile from the Region A user profile cache
3. the user profile cache's session ID member can now be set (written),
and is updated each time a connection with a new avatar is established (ie: a
new avatar enters the region)
4. when a region server looks up a user profile and a cache miss
occurs, fetch the user profile from the user server first instead of
immediately returning null
0.6.0-stable
Mike Mazur 2008-08-12 06:21:02 +00:00
parent 44adeb4ec8
commit 8ea92c0669
5 changed files with 43 additions and 72 deletions

View File

@ -86,7 +86,11 @@ namespace OpenSim.Framework.Communications.Cache
private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders
= new Dictionary<LLUUID, IList<InventoryFolderImpl>>(); = new Dictionary<LLUUID, IList<InventoryFolderImpl>>();
public LLUUID SessionID { get { return m_session_id; } } public LLUUID SessionID
{
get { return m_session_id; }
set { m_session_id = value; }
}
private LLUUID m_session_id = LLUUID.Zero; private LLUUID m_session_id = LLUUID.Zero;
/// <summary> /// <summary>
@ -100,21 +104,6 @@ namespace OpenSim.Framework.Communications.Cache
m_userProfile = userProfile; m_userProfile = userProfile;
} }
/// <summary>
/// Constructor
/// </summary>
/// <param name="commsManager"></param>
/// <param name="userProfile"></param>
/// <param name="sessionId">
/// Session id of the user. This is used in subsequent security checks.
/// </param>
public CachedUserInfo(CommunicationsManager commsManager, UserProfileData userProfile, LLUUID sessionId)
{
m_commsManager = commsManager;
m_userProfile = userProfile;
m_session_id = sessionId;
}
/// <summary> /// <summary>
/// This allows a request to be added to be processed once we receive a user's inventory /// This allows a request to be added to be processed once we receive a user's inventory
/// from the inventory service. If we already have the inventory, the request /// from the inventory service. If we already have the inventory, the request

View File

@ -59,35 +59,6 @@ namespace OpenSim.Framework.Communications.Cache
m_commsManager = commsManager; m_commsManager = commsManager;
} }
/// <summary>
/// A new user has moved into a region in this instance so retrieve their profile from the user service.
/// </summary>
/// <param name="userID"></param>
public void AddNewUser(IClientAPI remoteClient)
{
m_log.DebugFormat("[USER CACHE]: Adding user profile for {0} {1}", remoteClient.Name, remoteClient.AgentId);
// Potential fix - Multithreading issue.
lock (m_userProfiles)
{
if (!m_userProfiles.ContainsKey(remoteClient.AgentId))
{
UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(remoteClient.AgentId);
CachedUserInfo userInfo = new CachedUserInfo(m_commsManager, userProfile, remoteClient.SessionId);
if (userInfo.UserProfile != null)
{
// The inventory for the user will be populated when they actually enter the scene
m_userProfiles.Add(remoteClient.AgentId, userInfo);
}
else
{
m_log.ErrorFormat("[USER CACHE]: User profile for user {0} not found.", remoteClient.AgentId);
}
}
}
}
/// <summary> /// <summary>
/// A new user has moved into a region in this instance so retrieve their profile from the user service. /// A new user has moved into a region in this instance so retrieve their profile from the user service.
/// </summary> /// </summary>
@ -95,26 +66,7 @@ namespace OpenSim.Framework.Communications.Cache
public void AddNewUser(LLUUID userID) public void AddNewUser(LLUUID userID)
{ {
m_log.DebugFormat("[USER CACHE]: Adding user profile for {0}", userID); m_log.DebugFormat("[USER CACHE]: Adding user profile for {0}", userID);
GetUserDetails(userID);
// Potential fix - Multithreading issue.
lock (m_userProfiles)
{
if (!m_userProfiles.ContainsKey(userID))
{
UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID);
CachedUserInfo userInfo = new CachedUserInfo(m_commsManager, userProfile);
if (userInfo.UserProfile != null)
{
// The inventory for the user will be populated when they actually enter the scene
m_userProfiles.Add(userID, userInfo);
}
else
{
m_log.ErrorFormat("[USER CACHE]: User profile for user {0} not found.", userID);
}
}
}
} }
/// <summary> /// <summary>
@ -176,10 +128,28 @@ namespace OpenSim.Framework.Communications.Cache
/// <returns>null if no user details are found</returns> /// <returns>null if no user details are found</returns>
public CachedUserInfo GetUserDetails(LLUUID userID) public CachedUserInfo GetUserDetails(LLUUID userID)
{ {
if (m_userProfiles.ContainsKey(userID)) lock (m_userProfiles)
return m_userProfiles[userID]; {
else if (m_userProfiles.ContainsKey(userID))
return null; {
return m_userProfiles[userID];
}
else
{
UserProfileData userprofile = m_commsManager.UserService.GetUserProfile(userID);
if (userprofile != null)
{
CachedUserInfo userinfo = new CachedUserInfo(m_commsManager, userprofile);
m_userProfiles.Add(userID, userinfo);
return userinfo;
}
else
{
m_log.ErrorFormat("[USER CACHE]: User profile for user {0} not found.", userID);
return null;
}
}
}
} }
/// <summary> /// <summary>

View File

@ -2015,7 +2015,7 @@ namespace OpenSim.Region.Environment.Scenes
"[SCENE]: Adding new {0} agent {1} {2} in {3}", "[SCENE]: Adding new {0} agent {1} {2} in {3}",
(child ? "child" : "root"), client.Name, client.AgentId, RegionInfo.RegionName); (child ? "child" : "root"), client.Name, client.AgentId, RegionInfo.RegionName);
CommsManager.UserProfileCacheService.AddNewUser(client); CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
CreateAndAddScenePresence(client, child); CreateAndAddScenePresence(client, child);
} }
@ -2455,6 +2455,9 @@ namespace OpenSim.Region.Environment.Scenes
agent.circuitcode, agent.AgentID, RegionInfo.RegionName); agent.circuitcode, agent.AgentID, RegionInfo.RegionName);
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
// rewrite session_id
CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID);
userinfo.SessionID = agent.SessionID;
} }
else else
{ {

View File

@ -627,6 +627,11 @@ namespace OpenSim.Region.Environment.Scenes
{ {
SendCloseChildAgentConnections(avatar.UUID,avatar.GetKnownRegionList()); SendCloseChildAgentConnections(avatar.UUID,avatar.GetKnownRegionList());
} }
// if (teleport success) // seems to be always success here
// the user may change thier profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it
m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID);
} }
else else
{ {

View File

@ -1989,6 +1989,10 @@ namespace OpenSim.Region.Environment.Scenes
m_scene.SendKillObject(m_localId); m_scene.SendKillObject(m_localId);
m_scene.NotifyMyCoarseLocationChange(); m_scene.NotifyMyCoarseLocationChange();
// the user may change thier profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it
m_scene.CommsManager.UserProfileCacheService.RemoveUser(UUID);
m_log.InfoFormat("User {0} is going to another region, profile cache removed", UUID);
} }
else else
{ {