From 8ea92c0669de17f4967540ecc1350860aa346f06 Mon Sep 17 00:00:00 2001 From: Mike Mazur Date: Tue, 12 Aug 2008 06:21:02 +0000 Subject: 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 --- .../Communications/Cache/CachedUserInfo.cs | 23 ++----- .../Cache/UserProfileCacheService.cs | 78 +++++++--------------- OpenSim/Region/Environment/Scenes/Scene.cs | 5 +- .../Scenes/SceneCommunicationService.cs | 5 ++ OpenSim/Region/Environment/Scenes/ScenePresence.cs | 4 ++ 5 files changed, 43 insertions(+), 72 deletions(-) diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index d85eda0..57f5e76 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -85,8 +85,12 @@ namespace OpenSim.Framework.Communications.Cache /// private IDictionary> pendingCategorizationFolders = new Dictionary>(); - - 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; /// @@ -101,21 +105,6 @@ namespace OpenSim.Framework.Communications.Cache } /// - /// Constructor - /// - /// - /// - /// - /// Session id of the user. This is used in subsequent security checks. - /// - public CachedUserInfo(CommunicationsManager commsManager, UserProfileData userProfile, LLUUID sessionId) - { - m_commsManager = commsManager; - m_userProfile = userProfile; - m_session_id = sessionId; - } - - /// /// 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 /// is executed immediately instead. diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index c4a6b31..db58738 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs @@ -63,58 +63,10 @@ namespace OpenSim.Framework.Communications.Cache /// A new user has moved into a region in this instance so retrieve their profile from the user service. /// /// - 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); - } - } - } - } - - /// - /// A new user has moved into a region in this instance so retrieve their profile from the user service. - /// - /// 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); } /// @@ -176,10 +128,28 @@ namespace OpenSim.Framework.Communications.Cache /// null if no user details are found 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; + } + } + } } /// diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index f39a0e6..b54713f 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -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 { diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index cb37faf..348b643 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -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 { diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 1721acb..5c90bf3 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -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 { -- cgit v1.1