From d8f9b98c4ab700efcf4016b605461053c3b50fba Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 5 Aug 2010 22:50:09 +0200 Subject: [PATCH] Prevent hammering the grid services with llRequestAgentData requests. Cache the user information permanently, and the online status for 20 seconds. Also cache negatives. --- .../Shared/Api/Implementation/LSL_Api.cs | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bc47fa1900..ad7d650704 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -69,6 +69,14 @@ using System.Reflection; namespace OpenSim.Region.ScriptEngine.Shared.Api { + // MUST be a ref type + public class UserInfoCacheEntry + { + public int time; + public UserAccount account; + public PresenceInfo pinfo; + } + /// /// Contains all LSL ll-functions. This class will be in Default AppDomain. /// @@ -93,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int m_scriptConsoleChannel = 0; protected bool m_scriptConsoleChannelEnabled = false; protected IUrlModule m_UrlModule = null; + protected Dictionary m_userInfoCache = + new Dictionary(); public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) { @@ -4244,16 +4254,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID uuid = (UUID)id; - - UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); - if (account == null) - return UUID.Zero.ToString(); - - PresenceInfo pinfo = null; - PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); - if (pinfos != null && pinfos.Length > 0) - pinfo = pinfos[0]; + UserAccount account; + + UserInfoCacheEntry ce; + if (!m_userInfoCache.TryGetValue(uuid, out ce)) + { + account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); + if (account == null) + { + m_userInfoCache[uuid] = null; // Cache negative + return UUID.Zero.ToString(); + } + + + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + pinfo = pinfos[0]; + + ce = new UserInfoCacheEntry(); + ce.time = Util.EnvironmentTickCount(); + ce.account = account; + ce.pinfo = pinfo; + } + else + { + if (ce == null) + return UUID.Zero.ToString(); + + account = ce.account; + pinfo = ce.pinfo; + } + + if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) + { + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + pinfo = pinfos[0]; + + ce.time = Util.EnvironmentTickCount(); + ce.pinfo = pinfo; + } string reply = String.Empty;