From 9cefda83d6d54edc9ed1587bb71e9cb8fb2d17d5 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 29 May 2008 23:36:37 +0000 Subject: [PATCH] * Caches UUIDName requests * Looks up UUIDNames for script time and colliders in a separate thread. * Hopefully this'll allow you to look at top scripts on a region that has a lot of scripts without crashing your client thread. --- .../Communications/CommunicationsManager.cs | 61 ++++++++++++++++--- .../World/Estate/EstateManagementModule.cs | 50 ++++++++++++++- 2 files changed, 99 insertions(+), 12 deletions(-) diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs index 37020f6ceb..cc64e6cde0 100644 --- a/OpenSim/Framework/Communications/CommunicationsManager.cs +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -41,6 +41,7 @@ namespace OpenSim.Framework.Communications private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected IUserService m_userService; + protected Dictionary m_nameRequestCache = new Dictionary(); public IUserService UserService { @@ -248,27 +249,69 @@ namespace OpenSim.Framework.Communications } else { + string[] names = doUUIDNameRequest(uuid); + if (names.Length == 2) + { + remote_client.SendNameReply(uuid, names[0], names[1]); + } + + } + } + + private string[] doUUIDNameRequest(LLUUID uuid) + { + string[] returnstring = new string[0]; + bool doLookup = false; + + + lock (m_nameRequestCache) + { + if (m_nameRequestCache.ContainsKey(uuid)) + { + returnstring = m_nameRequestCache[uuid]; + } + else + { + // we don't want to lock the dictionary while we're doing the lookup + doLookup = true; + } + } + + if (doLookup) { UserProfileData profileData = m_userService.GetUserProfile(uuid); if (profileData != null) { + returnstring = new string[2]; LLUUID profileId = profileData.ID; - string firstname = profileData.FirstName; - string lastname = profileData.SurName; - - remote_client.SendNameReply(profileId, firstname, lastname); + returnstring[0] = profileData.FirstName; + returnstring[1] = profileData.SurName; + lock (m_nameRequestCache) + { + if (!m_nameRequestCache.ContainsKey(uuid)) + m_nameRequestCache.Add(uuid, returnstring); + } } } + return returnstring; + } + + public bool UUIDNameCachedTest(LLUUID uuid) + { + lock (m_nameRequestCache) + return m_nameRequestCache.ContainsKey(uuid); + } + public string UUIDNameRequestString(LLUUID uuid) { - UserProfileData profileData = m_userService.GetUserProfile(uuid); - if (profileData != null) + string[] names = doUUIDNameRequest(uuid); + if (names.Length == 2) { - //LLUUID profileId = profileData.ID; - string firstname = profileData.FirstName; - string lastname = profileData.SurName; + string firstname = names[0]; + string lastname = names[1]; return firstname + " " + lastname; + } return "(hippos)"; } diff --git a/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs index ab5898d697..6c63c36bbd 100644 --- a/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs @@ -24,7 +24,8 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +using System; +using System.Threading; using System.Collections.Generic; using System.Reflection; using libsecondlife; @@ -40,6 +41,8 @@ namespace OpenSim.Region.Environment.Modules.World.Estate { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private delegate void LookupUUIDS(List uuidLst); + private Scene m_scene; #region Packet Data Responders @@ -314,6 +317,7 @@ namespace OpenSim.Region.Environment.Modules.World.Estate private void HandleLandStatRequest(int parcelID, uint reportType, uint requestFlags, string filter, IClientAPI remoteClient) { Dictionary SceneData = new Dictionary(); + List uuidNameLookupList = new List(); if (reportType == 1) { @@ -345,7 +349,17 @@ namespace OpenSim.Region.Environment.Modules.World.Estate lsri.TaskID = sog.UUID; lsri.TaskLocalID = sog.LocalId; lsri.TaskName = sog.GetPartName(obj); - lsri.OwnerName = m_scene.CommsManager.UUIDNameRequestString(sog.OwnerID); + if (m_scene.CommsManager.UUIDNameCachedTest(sog.OwnerID)) + { + lsri.OwnerName = m_scene.CommsManager.UUIDNameRequestString(sog.OwnerID); + } + else + { + lsri.OwnerName = "waiting"; + lock(uuidNameLookupList) + uuidNameLookupList.Add(sog.OwnerID); + } + if (filter.Length != 0) { if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) @@ -365,9 +379,39 @@ namespace OpenSim.Region.Environment.Modules.World.Estate } } remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); - + + if (uuidNameLookupList.Count > 0) + LookupUUID(uuidNameLookupList); } + private void LookupUUIDSCompleted(IAsyncResult iar) + { + LookupUUIDS icon = (LookupUUIDS)iar.AsyncState; + icon.EndInvoke(iar); + } + private void LookupUUID(List uuidLst) + { + LookupUUIDS d = LookupUUIDsAsync; + + d.BeginInvoke(uuidLst, + LookupUUIDSCompleted, + d); + } + private void LookupUUIDsAsync(List uuidLst) + { + LLUUID[] uuidarr = new LLUUID[0]; + + lock (uuidLst) + { + uuidarr = uuidLst.ToArray(); + } + + for (int i = 0; i < uuidarr.Length; i++) + { + string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]); + // we drop it. It gets cached though... so we're ready for the next request. + } + } #endregion #region Outgoing Packets