* 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 lossage0.6.0-stable
parent
567a05a9e2
commit
269a2e4b88
|
@ -45,25 +45,31 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
/// The comms manager holds references to services (user, grid, inventory, etc.)
|
||||
/// </summary>
|
||||
private readonly CommunicationsManager m_commsManager;
|
||||
|
||||
private UserProfileData m_userProfile;
|
||||
|
||||
public UserProfileData UserProfile { get { return m_userProfile; } }
|
||||
private UserProfileData m_userProfile;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Has we received the user's inventory from the inventory service?
|
||||
/// </summary>
|
||||
private bool m_hasInventory;
|
||||
|
||||
/// <summary>
|
||||
/// Inventory requests waiting for receipt of this user's inventory from the inventory service.
|
||||
/// </summary>
|
||||
private readonly IList<IInventoryRequest> m_pendingRequests = new List<IInventoryRequest>();
|
||||
|
||||
/// <summary>
|
||||
/// Has this user info object yet received its inventory information from the invetnroy service?
|
||||
/// </summary>
|
||||
public bool HasInventory { get { return m_hasInventory; } }
|
||||
|
||||
// FIXME: These need to be hidden behind accessors
|
||||
private InventoryFolderImpl m_rootFolder;
|
||||
public InventoryFolderImpl RootFolder { get { return m_rootFolder; } }
|
||||
|
||||
/// <summary>
|
||||
/// Stores received folders for which we have not yet received the parents.
|
||||
/// </summary></param>
|
||||
/// FIXME: This could be contained within a local variable - it doesn't need to be a field
|
||||
/// </summary>
|
||||
private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders
|
||||
= new Dictionary<LLUUID, IList<InventoryFolderImpl>>();
|
||||
|
||||
|
@ -78,6 +84,27 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
m_userProfile = userProfile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This allows a request to be added to be processed once we receive a user's inventory
|
||||
/// from the inventory service. If we already have the inventory, the request
|
||||
/// is executed immediately instead.
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
public void AddRequest(IInventoryRequest request)
|
||||
{
|
||||
lock (m_pendingRequests)
|
||||
{
|
||||
if (m_hasInventory)
|
||||
{
|
||||
request.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pendingRequests.Add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Store a folder pending categorization when its parent is received.
|
||||
/// </summary>
|
||||
|
@ -148,8 +175,19 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
{
|
||||
m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e);
|
||||
}
|
||||
|
||||
m_hasInventory = true;
|
||||
|
||||
// Deal with pending requests
|
||||
lock (m_pendingRequests)
|
||||
{
|
||||
// We're going to change inventory status within the lock to avoid a race condition
|
||||
// where requests are processed after the AddRequest() method has been called.
|
||||
m_hasInventory = true;
|
||||
|
||||
foreach (IInventoryRequest request in m_pendingRequests)
|
||||
{
|
||||
request.Execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -288,4 +326,12 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be implemented by callers which require a callback when the user's inventory is received
|
||||
/// </summary>
|
||||
public interface IInventoryRequest
|
||||
{
|
||||
void Execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,6 +201,9 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
public void HandleUpdateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort type, string name,
|
||||
LLUUID parentID)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[AGENT INVENTORY] Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId);
|
||||
|
||||
CachedUserInfo userProfile;
|
||||
|
||||
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
|
||||
|
@ -216,6 +219,10 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
baseFolder.Version = userProfile.RootFolder.Version;
|
||||
m_commsManager.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, baseFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
userProfile.AddRequest(new UpdateFolderRequest(this, remoteClient, folderID, type, name, parentID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,4 +499,33 @@ namespace OpenSim.Framework.Communications.Cache
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to create an update folder request if we haven't yet received the user's inventory
|
||||
/// </summary>
|
||||
internal class UpdateFolderRequest : IInventoryRequest
|
||||
{
|
||||
private UserProfileCacheService m_userProfileCacheService;
|
||||
private IClientAPI m_client;
|
||||
private LLUUID m_folderID;
|
||||
private ushort m_type;
|
||||
private string m_name;
|
||||
private LLUUID m_parentID;
|
||||
|
||||
internal UpdateFolderRequest(
|
||||
UserProfileCacheService cacheService, IClientAPI client, LLUUID folderID, ushort type, string name, LLUUID parentID)
|
||||
{
|
||||
m_userProfileCacheService = cacheService;
|
||||
m_client = client;
|
||||
m_folderID = folderID;
|
||||
m_type = type;
|
||||
m_name = name;
|
||||
m_parentID = parentID;
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
m_userProfileCacheService.HandleUpdateInventoryFolder(m_client, m_folderID, m_type, m_name, m_parentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers
|
|||
using (WebResponse resp = request.GetResponse())
|
||||
{
|
||||
XmlSerializer deserializer = new XmlSerializer(typeof (TResponse));
|
||||
deserial = (TResponse) deserializer.Deserialize(resp.GetResponseStream());
|
||||
deserial = (TResponse) deserializer.Deserialize(resp.GetResponseStream());
|
||||
}
|
||||
return deserial;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
|
@ -108,7 +110,7 @@ namespace OpenSim.Grid.InventoryServer
|
|||
public InventoryCollection GetUserInventory(Guid rawUserID)
|
||||
{
|
||||
// uncomment me to simulate an overloaded inventory server
|
||||
//Thread.Sleep(25000);
|
||||
//Thread.Sleep(20000);
|
||||
|
||||
LLUUID userID = new LLUUID(rawUserID);
|
||||
|
||||
|
@ -165,6 +167,8 @@ namespace OpenSim.Grid.InventoryServer
|
|||
/// <returns></returns>
|
||||
public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
|
||||
{
|
||||
//Thread.Sleep(10000);
|
||||
|
||||
LLUUID userID = new LLUUID(rawUserID);
|
||||
return GetInventorySkeleton(userID);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue