aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-04-22 17:24:13 +0000
committerJustin Clarke Casey2008-04-22 17:24:13 +0000
commit269a2e4b887b9841309d4472508b19324a91d80d (patch)
tree46b73fce787b9e296c06265a66baba2caa92b8d4
parent* ODE Update! If you roll your own, make sure to download the lib source ag... (diff)
downloadopensim-SC_OLD-269a2e4b887b9841309d4472508b19324a91d80d.zip
opensim-SC_OLD-269a2e4b887b9841309d4472508b19324a91d80d.tar.gz
opensim-SC_OLD-269a2e4b887b9841309d4472508b19324a91d80d.tar.bz2
opensim-SC_OLD-269a2e4b887b9841309d4472508b19324a91d80d.tar.xz
* Allow folder renaming to complete after an agent inventory has been received by a region from the inventory service
* This replaces the old behaviour of failing straight away, which could cause lost updates if the inventory service was slow in responding * This is the first baby step to making all inventory requests behave this way, to reduce inventory lossage
-rw-r--r--OpenSim/Framework/Communications/Cache/CachedUserInfo.cs62
-rw-r--r--OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs36
-rw-r--r--OpenSim/Framework/Servers/SynchronousRestObjectPoster.cs2
-rw-r--r--OpenSim/Grid/InventoryServer/GridInventoryService.cs6
4 files changed, 96 insertions, 10 deletions
diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs
index a245af1..3d7ada3 100644
--- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs
+++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs
@@ -45,25 +45,31 @@ namespace OpenSim.Framework.Communications.Cache
45 /// The comms manager holds references to services (user, grid, inventory, etc.) 45 /// The comms manager holds references to services (user, grid, inventory, etc.)
46 /// </summary> 46 /// </summary>
47 private readonly CommunicationsManager m_commsManager; 47 private readonly CommunicationsManager m_commsManager;
48 48
49 private UserProfileData m_userProfile;
50 public UserProfileData UserProfile { get { return m_userProfile; } } 49 public UserProfileData UserProfile { get { return m_userProfile; } }
50 private UserProfileData m_userProfile;
51 51
52 52 /// <summary>
53 /// Has we received the user's inventory from the inventory service?
54 /// </summary>
53 private bool m_hasInventory; 55 private bool m_hasInventory;
54 56
55 /// <summary> 57 /// <summary>
58 /// Inventory requests waiting for receipt of this user's inventory from the inventory service.
59 /// </summary>
60 private readonly IList<IInventoryRequest> m_pendingRequests = new List<IInventoryRequest>();
61
62 /// <summary>
56 /// Has this user info object yet received its inventory information from the invetnroy service? 63 /// Has this user info object yet received its inventory information from the invetnroy service?
57 /// </summary> 64 /// </summary>
58 public bool HasInventory { get { return m_hasInventory; } } 65 public bool HasInventory { get { return m_hasInventory; } }
59 66
60 // FIXME: These need to be hidden behind accessors
61 private InventoryFolderImpl m_rootFolder; 67 private InventoryFolderImpl m_rootFolder;
62 public InventoryFolderImpl RootFolder { get { return m_rootFolder; } } 68 public InventoryFolderImpl RootFolder { get { return m_rootFolder; } }
63 69
64 /// <summary> 70 /// <summary>
65 /// Stores received folders for which we have not yet received the parents. 71 /// FIXME: This could be contained within a local variable - it doesn't need to be a field
66 /// </summary></param> 72 /// </summary>
67 private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders 73 private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders
68 = new Dictionary<LLUUID, IList<InventoryFolderImpl>>(); 74 = new Dictionary<LLUUID, IList<InventoryFolderImpl>>();
69 75
@@ -79,6 +85,27 @@ namespace OpenSim.Framework.Communications.Cache
79 } 85 }
80 86
81 /// <summary> 87 /// <summary>
88 /// This allows a request to be added to be processed once we receive a user's inventory
89 /// from the inventory service. If we already have the inventory, the request
90 /// is executed immediately instead.
91 /// </summary>
92 /// <param name="parent"></param>
93 public void AddRequest(IInventoryRequest request)
94 {
95 lock (m_pendingRequests)
96 {
97 if (m_hasInventory)
98 {
99 request.Execute();
100 }
101 else
102 {
103 m_pendingRequests.Add(request);
104 }
105 }
106 }
107
108 /// <summary>
82 /// Store a folder pending categorization when its parent is received. 109 /// Store a folder pending categorization when its parent is received.
83 /// </summary> 110 /// </summary>
84 /// <param name="folder"></param> 111 /// <param name="folder"></param>
@@ -148,8 +175,19 @@ namespace OpenSim.Framework.Communications.Cache
148 { 175 {
149 m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e); 176 m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e);
150 } 177 }
151 178
152 m_hasInventory = true; 179 // Deal with pending requests
180 lock (m_pendingRequests)
181 {
182 // We're going to change inventory status within the lock to avoid a race condition
183 // where requests are processed after the AddRequest() method has been called.
184 m_hasInventory = true;
185
186 foreach (IInventoryRequest request in m_pendingRequests)
187 {
188 request.Execute();
189 }
190 }
153 } 191 }
154 192
155 /// <summary> 193 /// <summary>
@@ -288,4 +326,12 @@ namespace OpenSim.Framework.Communications.Cache
288 return result; 326 return result;
289 } 327 }
290 } 328 }
329
330 /// <summary>
331 /// Should be implemented by callers which require a callback when the user's inventory is received
332 /// </summary>
333 public interface IInventoryRequest
334 {
335 void Execute();
336 }
291} 337}
diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
index bf8ff40..cbf2ded 100644
--- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
+++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
@@ -201,6 +201,9 @@ namespace OpenSim.Framework.Communications.Cache
201 public void HandleUpdateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort type, string name, 201 public void HandleUpdateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort type, string name,
202 LLUUID parentID) 202 LLUUID parentID)
203 { 203 {
204// m_log.DebugFormat(
205// "[AGENT INVENTORY] Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId);
206
204 CachedUserInfo userProfile; 207 CachedUserInfo userProfile;
205 208
206 if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) 209 if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
@@ -216,6 +219,10 @@ namespace OpenSim.Framework.Communications.Cache
216 baseFolder.Version = userProfile.RootFolder.Version; 219 baseFolder.Version = userProfile.RootFolder.Version;
217 m_commsManager.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, baseFolder); 220 m_commsManager.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, baseFolder);
218 } 221 }
222 else
223 {
224 userProfile.AddRequest(new UpdateFolderRequest(this, remoteClient, folderID, type, name, parentID));
225 }
219 } 226 }
220 } 227 }
221 228
@@ -492,4 +499,33 @@ namespace OpenSim.Framework.Communications.Cache
492 } 499 }
493 } 500 }
494 } 501 }
502
503 /// <summary>
504 /// Used to create an update folder request if we haven't yet received the user's inventory
505 /// </summary>
506 internal class UpdateFolderRequest : IInventoryRequest
507 {
508 private UserProfileCacheService m_userProfileCacheService;
509 private IClientAPI m_client;
510 private LLUUID m_folderID;
511 private ushort m_type;
512 private string m_name;
513 private LLUUID m_parentID;
514
515 internal UpdateFolderRequest(
516 UserProfileCacheService cacheService, IClientAPI client, LLUUID folderID, ushort type, string name, LLUUID parentID)
517 {
518 m_userProfileCacheService = cacheService;
519 m_client = client;
520 m_folderID = folderID;
521 m_type = type;
522 m_name = name;
523 m_parentID = parentID;
524 }
525
526 public void Execute()
527 {
528 m_userProfileCacheService.HandleUpdateInventoryFolder(m_client, m_folderID, m_type, m_name, m_parentID);
529 }
530 }
495} 531}
diff --git a/OpenSim/Framework/Servers/SynchronousRestObjectPoster.cs b/OpenSim/Framework/Servers/SynchronousRestObjectPoster.cs
index 1b8e4ea..103fbe5 100644
--- a/OpenSim/Framework/Servers/SynchronousRestObjectPoster.cs
+++ b/OpenSim/Framework/Servers/SynchronousRestObjectPoster.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers
75 using (WebResponse resp = request.GetResponse()) 75 using (WebResponse resp = request.GetResponse())
76 { 76 {
77 XmlSerializer deserializer = new XmlSerializer(typeof (TResponse)); 77 XmlSerializer deserializer = new XmlSerializer(typeof (TResponse));
78 deserial = (TResponse) deserializer.Deserialize(resp.GetResponseStream()); 78 deserial = (TResponse) deserializer.Deserialize(resp.GetResponseStream());
79 } 79 }
80 return deserial; 80 return deserial;
81 } 81 }
diff --git a/OpenSim/Grid/InventoryServer/GridInventoryService.cs b/OpenSim/Grid/InventoryServer/GridInventoryService.cs
index 82ba7df..fe892ca 100644
--- a/OpenSim/Grid/InventoryServer/GridInventoryService.cs
+++ b/OpenSim/Grid/InventoryServer/GridInventoryService.cs
@@ -28,6 +28,8 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Threading;
32
31using libsecondlife; 33using libsecondlife;
32using log4net; 34using log4net;
33using OpenSim.Framework; 35using OpenSim.Framework;
@@ -108,7 +110,7 @@ namespace OpenSim.Grid.InventoryServer
108 public InventoryCollection GetUserInventory(Guid rawUserID) 110 public InventoryCollection GetUserInventory(Guid rawUserID)
109 { 111 {
110 // uncomment me to simulate an overloaded inventory server 112 // uncomment me to simulate an overloaded inventory server
111 //Thread.Sleep(25000); 113 //Thread.Sleep(20000);
112 114
113 LLUUID userID = new LLUUID(rawUserID); 115 LLUUID userID = new LLUUID(rawUserID);
114 116
@@ -165,6 +167,8 @@ namespace OpenSim.Grid.InventoryServer
165 /// <returns></returns> 167 /// <returns></returns>
166 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID) 168 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
167 { 169 {
170 //Thread.Sleep(10000);
171
168 LLUUID userID = new LLUUID(rawUserID); 172 LLUUID userID = new LLUUID(rawUserID);
169 return GetInventorySkeleton(userID); 173 return GetInventorySkeleton(userID);
170 } 174 }