diff options
author | Justin Clarke Casey | 2008-04-14 18:43:23 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-04-14 18:43:23 +0000 |
commit | b7ae8701ce6881991fbacf28cdbb0d09f220f6ec (patch) | |
tree | 39247c37f31b9ad774a47e660eb9d314ef4c4582 | |
parent | * Fixed a few warnings. (diff) | |
download | opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.zip opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.tar.gz opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.tar.bz2 opensim-SC-b7ae8701ce6881991fbacf28cdbb0d09f220f6ec.tar.xz |
* Working towards notifying the client if the inventory service has failed, rather than simply returning 0 items.
* This is very early support which would only be triggered in a rather unlikely case (if the user server correctly received an inventory skeleton, but later on failed to return the whole inventory in a timely manner. Also, this only applies to the 1.19.1.4 client onwards
* Code cleanup and support for other failure cases (failure of inventory caching on region crossing, failure to actually add a folder/item, etc, should follow.
5 files changed, 70 insertions, 15 deletions
diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index 7995841..f746e8b 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs | |||
@@ -340,7 +340,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
340 | /// <param name="fetchFolders"></param> | 340 | /// <param name="fetchFolders"></param> |
341 | /// <param name="fetchItems"></param> | 341 | /// <param name="fetchItems"></param> |
342 | /// <param name="sortOrder"></param> | 342 | /// <param name="sortOrder"></param> |
343 | /// <returns></returns> | 343 | /// <returns>null if the inventory look up failed</returns> |
344 | public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, | 344 | public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, |
345 | bool fetchFolders, bool fetchItems, int sortOrder) | 345 | bool fetchFolders, bool fetchItems, int sortOrder) |
346 | { | 346 | { |
@@ -403,7 +403,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
403 | { | 403 | { |
404 | m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID.ToString()); | 404 | m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID.ToString()); |
405 | 405 | ||
406 | return new List<InventoryItemBase>(); ; | 406 | return null; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | else | 409 | else |
@@ -412,7 +412,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
412 | "[USER CACHE]: HandleFetchInventoryDescendentsCAPS() Could not find user profile for {0}", | 412 | "[USER CACHE]: HandleFetchInventoryDescendentsCAPS() Could not find user profile for {0}", |
413 | agentID); | 413 | agentID); |
414 | 414 | ||
415 | return new List<InventoryItemBase>(); | 415 | return null; |
416 | } | 416 | } |
417 | 417 | ||
418 | // If we've reached this point then we couldn't find the folder, even though the client thinks | 418 | // If we've reached this point then we couldn't find the folder, even though the client thinks |
diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs index f164208..46f50ad 100644 --- a/OpenSim/Framework/Communications/Capabilities/Caps.cs +++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs | |||
@@ -56,6 +56,13 @@ namespace OpenSim.Region.Capabilities | |||
56 | 56 | ||
57 | public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, | 57 | public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID, |
58 | bool fetchFolders, bool fetchItems, int sortOrder); | 58 | bool fetchFolders, bool fetchItems, int sortOrder); |
59 | |||
60 | /// <summary> | ||
61 | /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that | ||
62 | /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want | ||
63 | /// to just pass the whole Scene into CAPS. | ||
64 | /// </summary> | ||
65 | public delegate IClientAPI GetClientDelegate(LLUUID agentID); | ||
59 | 66 | ||
60 | public class Caps | 67 | public class Caps |
61 | { | 68 | { |
@@ -99,8 +106,8 @@ namespace OpenSim.Region.Capabilities | |||
99 | public NewInventoryItem AddNewInventoryItem = null; | 106 | public NewInventoryItem AddNewInventoryItem = null; |
100 | public ItemUpdatedCallback ItemUpdatedCall = null; | 107 | public ItemUpdatedCallback ItemUpdatedCall = null; |
101 | public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; | 108 | public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; |
102 | // | ||
103 | public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; | 109 | public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; |
110 | public GetClientDelegate GetClient = null; | ||
104 | 111 | ||
105 | public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath, | 112 | public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath, |
106 | LLUUID agent, bool dumpAssetsToFile) | 113 | LLUUID agent, bool dumpAssetsToFile) |
@@ -240,7 +247,7 @@ namespace OpenSim.Region.Capabilities | |||
240 | 247 | ||
241 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); | 248 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); |
242 | LLSDHelpers.DeserialiseLLSDMap(inventoryhash, llsdRequest); | 249 | LLSDHelpers.DeserialiseLLSDMap(inventoryhash, llsdRequest); |
243 | LLSDInventoryDescendents reply = FetchInventory(llsdRequest); | 250 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); |
244 | 251 | ||
245 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | 252 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); |
246 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | 253 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); |
@@ -265,7 +272,7 @@ namespace OpenSim.Region.Capabilities | |||
265 | return response; | 272 | return response; |
266 | } | 273 | } |
267 | 274 | ||
268 | private LLSDInventoryDescendents FetchInventory(LLSDFetchInventoryDescendents invFetch) | 275 | private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) |
269 | { | 276 | { |
270 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); | 277 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); |
271 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); | 278 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); |
@@ -289,6 +296,7 @@ namespace OpenSim.Region.Capabilities | |||
289 | { | 296 | { |
290 | itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order); | 297 | itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order); |
291 | } | 298 | } |
299 | |||
292 | if (itemList != null) | 300 | if (itemList != null) |
293 | { | 301 | { |
294 | foreach (InventoryItemBase invItem in itemList) | 302 | foreach (InventoryItemBase invItem in itemList) |
@@ -296,6 +304,27 @@ namespace OpenSim.Region.Capabilities | |||
296 | contents.items.Array.Add(ConvertInventoryItem(invItem)); | 304 | contents.items.Array.Add(ConvertInventoryItem(invItem)); |
297 | } | 305 | } |
298 | } | 306 | } |
307 | else | ||
308 | { | ||
309 | IClientAPI client = GetClient(m_agentID); | ||
310 | |||
311 | // We're going to both notify the client of inventory service failure and send back a 'no folder contents' response. | ||
312 | // If we don't send back the response, | ||
313 | // the client becomes unhappy (see Teravus' comment in FetchInventoryRequest()) | ||
314 | if (client != null) | ||
315 | { | ||
316 | client.SendAgentAlertMessage( | ||
317 | "AGIN0001E: The inventory service has either failed or is not responding. Your inventory will not function properly for the rest of this session. Please clear your cache and relog.", | ||
318 | true); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | m_log.ErrorFormat( | ||
323 | "[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure", | ||
324 | m_agentID); | ||
325 | } | ||
326 | } | ||
327 | |||
299 | contents.descendents = contents.items.Array.Count; | 328 | contents.descendents = contents.items.Array.Count; |
300 | return reply; | 329 | return reply; |
301 | } | 330 | } |
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 2599456..6ba40df 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs | |||
@@ -1576,7 +1576,8 @@ namespace OpenSim.Region.ClientStack | |||
1576 | } | 1576 | } |
1577 | 1577 | ||
1578 | /// <summary> | 1578 | /// <summary> |
1579 | /// | 1579 | /// Send an alert message to the client. On the Linden client (tested 1.19.1.4), this pops up a brief duration |
1580 | /// blue information box in the bottom right hand corner. | ||
1580 | /// </summary> | 1581 | /// </summary> |
1581 | /// <param name="message"></param> | 1582 | /// <param name="message"></param> |
1582 | public void SendAlertMessage(string message) | 1583 | public void SendAlertMessage(string message) |
@@ -1587,10 +1588,12 @@ namespace OpenSim.Region.ClientStack | |||
1587 | } | 1588 | } |
1588 | 1589 | ||
1589 | /// <summary> | 1590 | /// <summary> |
1590 | /// | 1591 | /// Send an agent alert message to the client. |
1591 | /// </summary> | 1592 | /// </summary> |
1592 | /// <param name="message"></param> | 1593 | /// <param name="message"></param> |
1593 | /// <param name="modal"></param> | 1594 | /// <param name="modal">On the linden client, if this true then it displays a one button text box placed in the |
1595 | /// middle of the window. If false, the message is displayed in a brief duration blue information box (as for | ||
1596 | /// the AlertMessage packet).</param> | ||
1594 | public void SendAgentAlertMessage(string message, bool modal) | 1597 | public void SendAgentAlertMessage(string message, bool modal) |
1595 | { | 1598 | { |
1596 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); | 1599 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); |
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index ef98599..0838387 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs | |||
@@ -618,6 +618,28 @@ namespace OpenSim.Region.Environment.Scenes | |||
618 | 618 | ||
619 | return result; | 619 | return result; |
620 | } | 620 | } |
621 | |||
622 | /// <summary> | ||
623 | /// Get the controlling client for the given avatar, if there is one. | ||
624 | /// | ||
625 | /// FIXME: The only user of the method right now is Caps.cs, in order to resolve a client API since it can't | ||
626 | /// use the ScenePresence. This could be better solved in a number of ways - we could establish an | ||
627 | /// OpenSim.Framework.IScenePresence, or move the caps code into a region package (which might be the more | ||
628 | /// suitable solution). | ||
629 | /// </summary> | ||
630 | /// <param name="agentId"></param> | ||
631 | /// <returns>null if either the avatar wasn't in the scene, or they do not have a controlling client</returns> | ||
632 | public IClientAPI GetControllingClient(LLUUID agentId) | ||
633 | { | ||
634 | ScenePresence presence = GetScenePresence(agentId); | ||
635 | |||
636 | if (presence != null) | ||
637 | { | ||
638 | return presence.ControllingClient; | ||
639 | } | ||
640 | |||
641 | return null; | ||
642 | } | ||
621 | 643 | ||
622 | /// <summary> | 644 | /// <summary> |
623 | /// Request a filtered list of m_scenePresences in this World | 645 | /// Request a filtered list of m_scenePresences in this World |
@@ -640,16 +662,17 @@ namespace OpenSim.Region.Environment.Scenes | |||
640 | } | 662 | } |
641 | 663 | ||
642 | /// <summary> | 664 | /// <summary> |
643 | /// Request a Avatar by UUID | 665 | /// Request a scene presence by UUID |
644 | /// </summary> | 666 | /// </summary> |
645 | /// <param name="avatarID"></param> | 667 | /// <param name="avatarID"></param> |
646 | /// <returns></returns> | 668 | /// <returns>null if the agent was not found</returns> |
647 | public ScenePresence GetScenePresence(LLUUID avatarID) | 669 | public ScenePresence GetScenePresence(LLUUID agentID) |
648 | { | 670 | { |
649 | if (ScenePresences.ContainsKey(avatarID)) | 671 | if (ScenePresences.ContainsKey(agentID)) |
650 | { | 672 | { |
651 | return ScenePresences[avatarID]; | 673 | return ScenePresences[agentID]; |
652 | } | 674 | } |
675 | |||
653 | return null; | 676 | return null; |
654 | } | 677 | } |
655 | 678 | ||
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 410120f..b93367c 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -1884,7 +1884,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1884 | cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; | 1884 | cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; |
1885 | cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset; | 1885 | cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset; |
1886 | cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS; | 1886 | cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS; |
1887 | 1887 | cap.GetClient = m_innerScene.GetControllingClient; | |
1888 | m_capsHandlers[agentId] = cap; | 1888 | m_capsHandlers[agentId] = cap; |
1889 | } | 1889 | } |
1890 | 1890 | ||