diff options
author | Justin Clarke Casey | 2008-04-22 17:24:13 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-04-22 17:24:13 +0000 |
commit | 269a2e4b887b9841309d4472508b19324a91d80d (patch) | |
tree | 46b73fce787b9e296c06265a66baba2caa92b8d4 /OpenSim | |
parent | * ODE Update! If you roll your own, make sure to download the lib source ag... (diff) | |
download | opensim-SC-269a2e4b887b9841309d4472508b19324a91d80d.zip opensim-SC-269a2e4b887b9841309d4472508b19324a91d80d.tar.gz opensim-SC-269a2e4b887b9841309d4472508b19324a91d80d.tar.bz2 opensim-SC-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
Diffstat (limited to 'OpenSim')
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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Threading; | ||
32 | |||
31 | using libsecondlife; | 33 | using libsecondlife; |
32 | using log4net; | 34 | using log4net; |
33 | using OpenSim.Framework; | 35 | using 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 | } |