From 91bfc2f62cec800a1413ec4dfb9b87aef1d2b0ed Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Jan 2021 20:37:44 +0000 Subject: [PATCH] reduce (again) number of http requestes on getdisplaynames --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- .../UserManagement/UserManagementModule.cs | 266 ++++++++++++++++-- .../Services/Interfaces/IUserManagement.cs | 3 +- 3 files changed, 249 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index d29883ba30..84bd60cc6e 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -2288,7 +2288,7 @@ namespace OpenSim.Region.ClientStack.Linden NameValueCollection query = httpRequest.QueryString; string[] ids = query.GetValues("ids"); - Dictionary names = m_UserManager.GetUsersNames(ids, m_scopeID); + Dictionary names = m_UserManager.GetKnownUserNames(ids, m_scopeID); osUTF8 lsl = LLSDxmlEncode2.Start(names.Count * 256 + 256); LLSDxmlEncode2.AddMap(lsl); int ct = 0; diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index ffa64de9b2..27ae663c8a 100755 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -409,21 +409,249 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public virtual Dictionary GetUsersNames(string[] ids, UUID scopeID) { - Dictionary ret = new Dictionary(); + var ret = new Dictionary(); if(m_Scenes.Count <= 0) return ret; - UserData userdata = new UserData(); - UUID uuid = UUID.Zero; - foreach(string id in ids) + List missing = new List(ids.Length); + var untried = new Dictionary(); + foreach (string id in ids) { - if(UUID.TryParse(id, out uuid)) + if(!UUID.TryParse(id, out UUID uuid) || uuid == UUID.Zero) + continue; + + if (m_userCacheByID.TryGetValue(uuid, out UserData userdata)) { - if (GetUser(uuid, out userdata)) - ret[uuid] = userdata.FirstName + " " + userdata.LastName; - else - ret[uuid] = "Unknown " + uuid.ToString() + "UMM1"; + string name = userdata.FirstName + " " + userdata.LastName; + if (userdata.HasGridUserTried) + { + ret[uuid] = name; + continue; + } + untried[uuid] = userdata; } + missing.Add(id); + } + + if(missing.Count == 0) + return ret; + + ids = null; + + List accounts = m_userAccountService.GetUserAccounts(scopeID, missing); + if (accounts.Count != 0) + { + foreach (UserAccount uac in accounts) + { + if (uac != null) + { + string name = uac.FirstName + " " + uac.LastName; + UUID id = uac.PrincipalID; + ret[id] = name; + missing.Remove(uac.PrincipalID.ToString()); // slowww + untried.Remove(uac.PrincipalID); + + var userdata = new UserData(); + userdata.Id = id; + userdata.FirstName = uac.FirstName; + userdata.LastName = uac.LastName; + userdata.HomeURL = string.Empty; + userdata.IsUnknownUser = false; + userdata.HasGridUserTried = true; + m_userCacheByID.Add(id, userdata, 1800000); + } + } + } + + if (missing.Count == 0 || m_gridUserService == null) + return ret; + + GridUserInfo[] pinfos = m_gridUserService.GetGridUserInfo(missing.ToArray()); + if (pinfos.Length > 0) + { + foreach (GridUserInfo uInfo in pinfos) + { + if (uInfo != null && uInfo.UserID.Length >= 36) + { + string url, first, last, tmp; + UUID u; + if (uInfo.UserID.Length >= 36 && Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp)) + { + bool isvalid = CheckUrl(url, out bool islocal, out OSHHTPHost host); + var userdata = new UserData(); + userdata.Id = u; + if (isvalid) + { + if (islocal) + { + userdata.FirstName = first; + userdata.LastName = last; + userdata.HomeURL = string.Empty; + userdata.IsLocal = true; + } + else + { + userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); + userdata.HomeURL = host.URI; + userdata.LastName = "@" + host.HostAndPort; + userdata.IsLocal = false; + } + userdata.IsUnknownUser = false; + userdata.HasGridUserTried = true; + m_userCacheByID.Add(u, userdata, 1800000); + + string name = userdata.FirstName + " " + userdata.LastName; + ret[u] = name; + missing.Remove(u.ToString()); + untried.Remove(u); + } + } + else + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID); + } + } + } + + // add the untried in cache + if (untried.Count > 0) + { + foreach (UserData ud in untried.Values) + { + UUID id = ud.Id; + ud.HasGridUserTried = true; + m_userCacheByID.Add(id, ud, 1800000); + + ret[id] = ud.FirstName + " " + ud.LastName; + missing.Remove(id.ToString()); + } + } + + // add the UMMthings ( not sure we should) + if (missing.Count > 0) + { + foreach (string id in missing) + { + if (UUID.TryParse(id, out UUID uuid)) + ret[uuid] = "Unknown UserUMMAU43"; + } + } + + return ret; + } + + public virtual Dictionary GetKnownUserNames(string[] ids, UUID scopeID) + { + var ret = new Dictionary(); + if (m_Scenes.Count <= 0) + return ret; + + List missing = new List(ids.Length); + var untried = new Dictionary(); + foreach (string id in ids) + { + if (!UUID.TryParse(id, out UUID uuid) || uuid == UUID.Zero) + continue; + + if (m_userCacheByID.TryGetValue(uuid, out UserData userdata)) + { + if (userdata.HasGridUserTried) + { + if(!userdata.IsUnknownUser) + ret[uuid] = userdata.FirstName + " " + userdata.LastName; + continue; + } + else + untried[uuid] = userdata; + } + missing.Add(id); + } + + if (missing.Count == 0) + return ret; + + ids = null; + + List accounts = m_userAccountService.GetUserAccounts(scopeID, missing); + if (accounts.Count != 0) + { + foreach (UserAccount uac in accounts) + { + if (uac != null) + { + UUID id = uac.PrincipalID; + + var userdata = new UserData(); + userdata.Id = id; + userdata.FirstName = uac.FirstName; + userdata.LastName = uac.LastName; + userdata.HomeURL = string.Empty; + userdata.IsUnknownUser = false; + userdata.HasGridUserTried = true; + m_userCacheByID.Add(id, userdata, 1800000); + + ret[id] = uac.FirstName + " " + uac.LastName; + missing.Remove(id.ToString()); // slowww + untried.Remove(id); + } + } + } + + if (missing.Count == 0 || m_gridUserService == null) + return ret; + + GridUserInfo[] pinfos = m_gridUserService.GetGridUserInfo(missing.ToArray()); + missing = null; + if (pinfos.Length > 0) + { + foreach (GridUserInfo uInfo in pinfos) + { + if (uInfo != null && uInfo.UserID.Length >= 36) + { + string url, first, last, tmp; + UUID uuid; + if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out uuid, out url, out first, out last, out tmp)) + { + bool isvalid = CheckUrl(url, out bool islocal, out OSHHTPHost host); + var userdata = new UserData(); + userdata.Id = uuid; + if (isvalid) + { + if (islocal) + { + userdata.FirstName = first; + userdata.LastName = last; + userdata.HomeURL = string.Empty; + userdata.IsLocal = true; + } + else + { + userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); + userdata.HomeURL = host.URI; + userdata.LastName = "@" + host.HostAndPort; + userdata.IsLocal = false; + } + + userdata.IsUnknownUser = false; + userdata.HasGridUserTried = true; + m_userCacheByID.Add(uuid, userdata, 1800000); + + string name = userdata.FirstName + " " + userdata.LastName; + untried.Remove(uuid); + ret[uuid] = name; + } + } + else + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID); + } + } + } + + foreach(UserData ud in untried.Values) + { + ud.HasGridUserTried = true; + m_userCacheByID.Add(ud.Id, ud, 1800000); + if(!ud.IsUnknownUser) + ret[ud.Id] = ud.FirstName + " " + ud.LastName; } return ret; } @@ -602,12 +830,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public virtual bool GetUserUUI(UUID userID, out string uui) { - bool result = GetUser(userID, out UserData ud); - - if (ud != null) + if (GetUser(userID, out UserData ud) && ud != null) { string homeURL = ud.HomeURL; - string first = ud.FirstName, last = ud.LastName; + string first = ud.FirstName, + last = ud.LastName; if (ud.LastName.StartsWith("@")) { string[] parts = ud.FirstName.Split('.'); @@ -616,13 +843,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement first = parts[0]; last = parts[1]; } - uui = userID + ";" + homeURL + ";" + first + " " + last; - return result; + uui = userID.ToString() + ";" + homeURL + ";" + first + " " + last; } + else + uui = userID.ToString(); + return true; } uui = userID.ToString(); - return result; + return false; } #region Cache Management @@ -961,10 +1190,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement protected virtual void HandleResetUserCache(string module, string[] cmd) { - lock(m_userCacheByID) - { - m_userCacheByID.Clear(); - } + m_userCacheByID.Clear(); } protected virtual void HandleShowUser(string module, string[] cmd) diff --git a/OpenSim/Services/Interfaces/IUserManagement.cs b/OpenSim/Services/Interfaces/IUserManagement.cs index c3b53bb759..3abbc151f2 100644 --- a/OpenSim/Services/Interfaces/IUserManagement.cs +++ b/OpenSim/Services/Interfaces/IUserManagement.cs @@ -46,7 +46,8 @@ namespace OpenSim.Framework bool GetUserUUI(UUID userID, out string uui); string GetUserServerURL(UUID uuid, string serverType); string GetUserServerURL(UUID uuid, string serverType, out bool failedWeb); - Dictionary GetUsersNames(string[] ids, UUID scopeID); + Dictionary GetUsersNames(string[] ids, UUID scopeID); + Dictionary GetKnownUserNames(string[] ids, UUID scopeID); void UserWebFailed(UUID id); ///