From a5176c2e2c4d2791ec15a22db4309bb15bc3ae98 Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Fri, 11 Apr 2008 18:13:10 +0000
Subject: * Change inventory async response deliver to deliver all items and
folders at once, rather than each individual * This is required in order to
work towards eliminating some inventory race conditions and to better deal
with situations where a grid inventory server is slow or not responding.
---
.../Communications/Cache/CachedUserInfo.cs | 109 ++++++++++++++-------
.../Cache/UserProfileCacheService.cs | 16 ++-
.../Framework/Communications/IInventoryServices.cs | 19 +++-
.../Communications/InventoryServiceBase.cs | 5 +-
OpenSim/Framework/InventoryCollection.cs | 3 +
.../Grid/InventoryServer/GridInventoryService.cs | 3 +-
.../Communications/Local/LocalInventoryService.cs | 45 +++------
.../Communications/OGS1/OGS1InventoryService.cs | 40 +++++---
8 files changed, 151 insertions(+), 89 deletions(-)
diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs
index 1208605..cf701cb 100644
--- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs
+++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs
@@ -118,64 +118,82 @@ namespace OpenSim.Framework.Communications.Cache
}
}
}
-
+
///
- /// Callback invoked when a folder is received from an async request to the inventory service.
+ /// Callback invoked when the inventory is received from an async request to the inventory service
///
///
- ///
- public void FolderReceive(LLUUID userID, InventoryFolderImpl folderInfo)
+ ///
+ public void InventoryReceive(LLUUID userID, ICollection folders, ICollection items)
{
// FIXME: Exceptions thrown upwards never appear on the console. Could fix further up if these
// are simply being swallowed
try
+ {
+ foreach (InventoryFolderImpl folder in folders)
+ {
+ FolderReceive(userID, folder);
+ }
+
+ foreach (InventoryItemBase item in items)
+ {
+ ItemReceive(userID, item);
+ }
+ }
+ catch (Exception e)
{
+ m_log.ErrorFormat("[INVENTORY CACHE]: {0}", e);
+ }
+ }
+
+ ///
+ /// Callback invoked when a folder is received from an async request to the inventory service.
+ ///
+ ///
+ ///
+ private void FolderReceive(LLUUID userID, InventoryFolderImpl folderInfo)
+ {
// m_log.DebugFormat(
// "[INVENTORY CACHE]: Received folder {0} {1} for user {2}",
// folderInfo.name, folderInfo.folderID, userID);
-
- if (userID == UserProfile.ID)
+
+ if (userID == UserProfile.ID)
+ {
+ if (RootFolder == null)
{
- if (RootFolder == null)
+ if (folderInfo.ParentID == LLUUID.Zero)
{
- if (folderInfo.ParentID == LLUUID.Zero)
- {
- m_rootFolder = folderInfo;
- }
+ m_rootFolder = folderInfo;
}
- else if (RootFolder.ID == folderInfo.ParentID)
+ }
+ else if (RootFolder.ID == folderInfo.ParentID)
+ {
+ if (!RootFolder.SubFolders.ContainsKey(folderInfo.ID))
{
- if (!RootFolder.SubFolders.ContainsKey(folderInfo.ID))
- {
- RootFolder.SubFolders.Add(folderInfo.ID, folderInfo);
- }
- else
- {
- AddPendingFolder(folderInfo);
- }
+ RootFolder.SubFolders.Add(folderInfo.ID, folderInfo);
}
else
{
- InventoryFolderImpl folder = RootFolder.HasSubFolder(folderInfo.ParentID);
- if (folder != null)
- {
- if (!folder.SubFolders.ContainsKey(folderInfo.ID))
- {
- folder.SubFolders.Add(folderInfo.ID, folderInfo);
- }
- }
- else
+ AddPendingFolder(folderInfo);
+ }
+ }
+ else
+ {
+ InventoryFolderImpl folder = RootFolder.HasSubFolder(folderInfo.ParentID);
+ if (folder != null)
+ {
+ if (!folder.SubFolders.ContainsKey(folderInfo.ID))
{
- AddPendingFolder(folderInfo);
+ folder.SubFolders.Add(folderInfo.ID, folderInfo);
}
}
-
- ResolvePendingFolders(folderInfo);
+ else
+ {
+ AddPendingFolder(folderInfo);
+ }
}
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[INVENTORY CACHE] {0}", e);
+
+ ResolvePendingFolders(folderInfo);
}
}
@@ -187,7 +205,7 @@ namespace OpenSim.Framework.Communications.Cache
///
///
///
- public void ItemReceive(LLUUID userID, InventoryItemBase itemInfo)
+ private void ItemReceive(LLUUID userID, InventoryItemBase itemInfo)
{
if ((userID == UserProfile.ID) && (RootFolder != null))
{
@@ -212,6 +230,11 @@ namespace OpenSim.Framework.Communications.Cache
}
}
+ ///
+ /// Add an item to the user's inventory
+ ///
+ ///
+ ///
public void AddItem(LLUUID userID, InventoryItemBase itemInfo)
{
if ((userID == UserProfile.ID) && HasInventory)
@@ -221,6 +244,11 @@ namespace OpenSim.Framework.Communications.Cache
}
}
+ ///
+ /// Update an item in the user's inventory
+ ///
+ ///
+ ///
public void UpdateItem(LLUUID userID, InventoryItemBase itemInfo)
{
if ((userID == UserProfile.ID) && HasInventory)
@@ -229,6 +257,12 @@ namespace OpenSim.Framework.Communications.Cache
}
}
+ ///
+ /// Delete an item from the user's inventory
+ ///
+ ///
+ ///
+ ///
public bool DeleteItem(LLUUID userID, InventoryItemBase item)
{
bool result = false;
@@ -240,6 +274,7 @@ namespace OpenSim.Framework.Communications.Cache
m_commsManager.InventoryService.DeleteInventoryItem(userID, item);
}
}
+
return result;
}
}
diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
index b924d5c..6b09e01 100644
--- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
+++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs
@@ -97,7 +97,7 @@ namespace OpenSim.Framework.Communications.Cache
CachedUserInfo userInfo = GetUserDetails(userID);
if (userInfo != null)
{
- m_commsManager.InventoryService.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive);
+ m_commsManager.InventoryService.RequestInventoryForUser(userID, userInfo.InventoryReceive);
}
else
{
@@ -118,6 +118,14 @@ namespace OpenSim.Framework.Communications.Cache
return null;
}
+ ///
+ /// Handle an inventory folder creation request from the client.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType,
string folderName, LLUUID parentID)
{
@@ -189,6 +197,12 @@ namespace OpenSim.Framework.Communications.Cache
}
}
+ ///
+ /// Handle an inventory folder move request from the client.
+ ///
+ ///
+ ///
+ ///
public void HandleMoveInventoryFolder(IClientAPI remoteClient, LLUUID folderID, LLUUID parentID)
{
CachedUserInfo userProfile;
diff --git a/OpenSim/Framework/Communications/IInventoryServices.cs b/OpenSim/Framework/Communications/IInventoryServices.cs
index ecc6c71..40e7ffd 100644
--- a/OpenSim/Framework/Communications/IInventoryServices.cs
+++ b/OpenSim/Framework/Communications/IInventoryServices.cs
@@ -26,21 +26,34 @@
*/
using System.Collections.Generic;
+
using libsecondlife;
+
using OpenSim.Framework.Communications.Cache;
namespace OpenSim.Framework.Communications
{
- public delegate void InventoryFolderInfo(LLUUID userID, InventoryFolderImpl folderInfo);
+ ///
+ /// Callback used when a user's inventory is received from the inventory service
+ ///
+ public delegate void InventoryReceiptCallback(LLUUID userId, ICollection folders, ICollection items);
+
+ //public delegate void InventoryFolderInfo(LLUUID userID, InventoryFolderImpl folderInfo);
- public delegate void InventoryItemInfo(LLUUID userID, InventoryItemBase itemInfo);
+ //public delegate void InventoryItemInfo(LLUUID userID, InventoryItemBase itemInfo);
///
/// Defines all the operations one can perform on a user's inventory.
///
public interface IInventoryServices
{
- void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack);
+ ///
+ /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
+ /// inventory has been received
+ ///
+ ///
+ ///
+ void RequestInventoryForUser(LLUUID userID, InventoryReceiptCallback callback);
///
/// Add a new folder to the given user's inventory
diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs
index e50e19e..aedf4b3 100644
--- a/OpenSim/Framework/Communications/InventoryServiceBase.cs
+++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs
@@ -158,8 +158,9 @@ namespace OpenSim.Framework.Communications
return false;
}
- public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack,
- InventoryItemInfo itemCallBack);
+ // See IInventoryServices
+ public abstract void RequestInventoryForUser(LLUUID userID, InventoryReceiptCallback callback);
+
public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder);
public abstract void MoveExistingInventoryFolder(InventoryFolderBase folder);
public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item);
diff --git a/OpenSim/Framework/InventoryCollection.cs b/OpenSim/Framework/InventoryCollection.cs
index c8d8716..e76e1a9 100644
--- a/OpenSim/Framework/InventoryCollection.cs
+++ b/OpenSim/Framework/InventoryCollection.cs
@@ -32,6 +32,9 @@ using libsecondlife;
namespace OpenSim.Framework
{
+ ///
+ /// Used to serialize a whole inventory for transfer over the network.
+ ///
public class InventoryCollection
{
public List _folders;
diff --git a/OpenSim/Grid/InventoryServer/GridInventoryService.cs b/OpenSim/Grid/InventoryServer/GridInventoryService.cs
index 1ae5243..72d43d4 100644
--- a/OpenSim/Grid/InventoryServer/GridInventoryService.cs
+++ b/OpenSim/Grid/InventoryServer/GridInventoryService.cs
@@ -41,8 +41,7 @@ namespace OpenSim.Grid.InventoryServer
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- public override void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack,
- InventoryItemInfo itemCallBack)
+ public override void RequestInventoryForUser(LLUUID userID, InventoryReceiptCallback callback)
{
}
diff --git a/OpenSim/Region/Communications/Local/LocalInventoryService.cs b/OpenSim/Region/Communications/Local/LocalInventoryService.cs
index bb3db9d..13cb6de 100644
--- a/OpenSim/Region/Communications/Local/LocalInventoryService.cs
+++ b/OpenSim/Region/Communications/Local/LocalInventoryService.cs
@@ -39,32 +39,38 @@ namespace OpenSim.Region.Communications.Local
///
public class LocalInventoryService : InventoryServiceBase
{
- public override void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack,
- InventoryItemInfo itemCallBack)
+ public override void RequestInventoryForUser(LLUUID userID, InventoryReceiptCallback callback)
{
- List folders = GetInventorySkeleton(userID);
-
+ List skeletonFolders = GetInventorySkeleton(userID);
InventoryFolderImpl rootFolder = null;
+
+ ICollection folders = new List();
+ ICollection items = new List();
- //need to make sure we send root folder first
- foreach (InventoryFolderBase folder in folders)
+ // Need to retrieve the root folder on the first pass
+ foreach (InventoryFolderBase folder in skeletonFolders)
{
if (folder.ParentID == LLUUID.Zero)
{
- rootFolder = RequestInventoryFolder(userID, folder, folderCallBack, itemCallBack);
+ //rootFolder = RequestInventoryFolder(userID, folder, callback);
+ rootFolder = new InventoryFolderImpl(folder);
+ folders.Add(rootFolder);
}
}
if (rootFolder != null)
{
- foreach (InventoryFolderBase folder in folders)
+ foreach (InventoryFolderBase folder in skeletonFolders)
{
if (folder.ID != rootFolder.ID)
{
- RequestInventoryFolder(userID, folder, folderCallBack, itemCallBack);
+ //RequestInventoryFolder(userID, folder, callback);
+ folders.Add(new InventoryFolderImpl(folder));
}
}
}
+
+ callback(userID, folders, items);
}
public override void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder)
@@ -99,26 +105,5 @@ namespace OpenSim.Region.Communications.Local
return true;
}
}
-
- ///
- /// Send the given inventory folder and its item contents back to the requester.
- ///
- ///
- ///
- private InventoryFolderImpl RequestInventoryFolder(LLUUID userID, InventoryFolderBase folder,
- InventoryFolderInfo folderCallBack,
- InventoryItemInfo itemCallBack)
- {
- InventoryFolderImpl newFolder = new InventoryFolderImpl(folder);
- folderCallBack(userID, newFolder);
-
- List items = RequestFolderItems(newFolder.ID);
- foreach (InventoryItemBase item in items)
- {
- itemCallBack(userID, item);
- }
-
- return newFolder;
- }
}
}
diff --git a/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs b/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs
index b18c5bf..f31127f 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs
@@ -51,12 +51,11 @@ namespace OpenSim.Region.Communications.OGS1
#region IInventoryServices Members
// See IInventoryServices
- public void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack,
- InventoryItemInfo itemCallBack)
+ public void RequestInventoryForUser(LLUUID userID, InventoryReceiptCallback callback)
{
if (!m_RequestingInventory.ContainsKey(userID))
{
- InventoryRequest request = new InventoryRequest(userID, folderCallBack, itemCallBack);
+ InventoryRequest request = new InventoryRequest(userID, callback);
m_RequestingInventory.Add(userID, request);
RequestInventory(userID);
}
@@ -105,13 +104,17 @@ namespace OpenSim.Region.Communications.OGS1
InventoryFolderImpl rootFolder = null;
InventoryRequest request = m_RequestingInventory[userID];
+
+ ICollection folders = new List();
+ ICollection items = new List();
+
foreach (InventoryFolderBase folder in response.Folders)
{
if (folder.ParentID == LLUUID.Zero)
{
- InventoryFolderImpl newfolder = new InventoryFolderImpl(folder);
- rootFolder = newfolder;
- request.FolderCallBack(userID, newfolder);
+ rootFolder = new InventoryFolderImpl(folder);
+ folders.Add(rootFolder);
+ //request.FolderCallBack(userID, newfolder);
}
}
@@ -121,16 +124,20 @@ namespace OpenSim.Region.Communications.OGS1
{
if (folder.ID != rootFolder.ID)
{
- InventoryFolderImpl newfolder = new InventoryFolderImpl(folder);
- request.FolderCallBack(userID, newfolder);
+ folders.Add(new InventoryFolderImpl(folder));
+ //request.FolderCallBack(userID, newfolder);
}
}
foreach (InventoryItemBase item in response.AllItems)
{
- request.ItemCallBack(userID, item);
+ items.Add(item);
+ //request.ItemCallBack(userID, item);
}
}
+
+ request.Callback(userID, folders, items);
+
m_RequestingInventory.Remove(userID);
}
else
@@ -223,17 +230,22 @@ namespace OpenSim.Region.Communications.OGS1
#endregion
+ ///
+ /// Caches a pending inventory request that has yet to be satisfied by the inventory service
+ ///
public class InventoryRequest
{
public LLUUID UserID;
- public InventoryFolderInfo FolderCallBack;
- public InventoryItemInfo ItemCallBack;
+ public InventoryReceiptCallback Callback;
+ //public InventoryFolderInfo FolderCallBack;
+ //public InventoryItemInfo ItemCallBack;
- public InventoryRequest(LLUUID userId, InventoryFolderInfo folderCall, InventoryItemInfo itemCall)
+ public InventoryRequest(LLUUID userId, InventoryReceiptCallback callback)
{
UserID = userId;
- FolderCallBack = folderCall;
- ItemCallBack = itemCall;
+ //FolderCallBack = folderCall;
+ //ItemCallBack = itemCall;
+ Callback = callback;
}
}
}
--
cgit v1.1