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>
|
/// </summary>
|
||||||
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
|
||||||
|
|
|
@ -59,62 +59,14 @@ 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>
|
||||||
/// <param name="userID"></param>
|
/// <param name="userID"></param>
|
||||||
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>
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue