Browse Source

* 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.

Teravus Ovares 16 years ago
parent
commit
9cefda83d6

+ 52 - 9
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<LLUUID, string[]> m_nameRequestCache = new Dictionary<LLUUID, string[]>();
 
         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)";
         }

+ 46 - 2
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<LLUUID> 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<uint, float> SceneData = new Dictionary<uint,float>();
+            List<LLUUID> uuidNameLookupList = new List<LLUUID>();
 
             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<LLUUID> uuidLst)
+        {
+            LookupUUIDS d = LookupUUIDsAsync;
 
+            d.BeginInvoke(uuidLst,
+                          LookupUUIDSCompleted,
+                          d);
         }
+        private void LookupUUIDsAsync(List<LLUUID> 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