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 null0.6.0-stable
parent
44adeb4ec8
commit
8ea92c0669
|
@ -85,8 +85,12 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
/// </summary>
|
||||
private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders
|
||||
= 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;
|
||||
|
||||
/// <summary>
|
||||
|
@ -100,21 +104,6 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
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>
|
||||
/// 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
|
||||
|
|
|
@ -59,62 +59,14 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
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>
|
||||
/// 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(LLUUID userID)
|
||||
{
|
||||
m_log.DebugFormat("[USER CACHE]: Adding user profile for {0}", 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_log.DebugFormat("[USER CACHE]: Adding user profile for {0}", userID);
|
||||
GetUserDetails(userID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -176,10 +128,28 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
/// <returns>null if no user details are found</returns>
|
||||
public CachedUserInfo GetUserDetails(LLUUID userID)
|
||||
{
|
||||
if (m_userProfiles.ContainsKey(userID))
|
||||
return m_userProfiles[userID];
|
||||
else
|
||||
return null;
|
||||
lock (m_userProfiles)
|
||||
{
|
||||
if (m_userProfiles.ContainsKey(userID))
|
||||
{
|
||||
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>
|
||||
|
|
|
@ -2015,7 +2015,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
"[SCENE]: Adding new {0} agent {1} {2} in {3}",
|
||||
(child ? "child" : "root"), client.Name, client.AgentId, RegionInfo.RegionName);
|
||||
|
||||
CommsManager.UserProfileCacheService.AddNewUser(client);
|
||||
CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
|
||||
|
||||
CreateAndAddScenePresence(client, child);
|
||||
}
|
||||
|
@ -2455,6 +2455,9 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
agent.circuitcode, agent.AgentID, RegionInfo.RegionName);
|
||||
|
||||
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
|
||||
// rewrite session_id
|
||||
CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID);
|
||||
userinfo.SessionID = agent.SessionID;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -627,6 +627,11 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -1989,6 +1989,10 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
m_scene.SendKillObject(m_localId);
|
||||
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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue