From 3d033520fafa1431c52086d741d1f3c7409bc6eb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 7 Sep 2010 00:34:06 +0100 Subject: Fix deletion persistence when freshly delinked prims are removed Previously, Scene.Inventory.DeRezObjects() forced the persistence of prims before deletion. This is necessary so that freshly delinked prims can be deleted (otherwise they remain as parts of their old group and reappear on server restart). However, DeRezObjects() deleted to user inventory, which is not required by llDie() or direct region module unlink and deletion. Therefore, forced persistence has been pushed down into Scene.UnlinkSceneObject() to be more general, this is still on the DeRezObjects() path. Uncommented TestDelinkPersistence() since this now passes. Tests required considerable elaboration of MockRegionDataPlugin to reflect underlying storing of parts. --- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 21 ++++++----- OpenSim/Region/Framework/Scenes/EntityBase.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 7 +--- OpenSim/Region/Framework/Scenes/Scene.cs | 25 ++++++++----- .../Region/Framework/Scenes/SceneObjectGroup.cs | 42 +++++++++++++--------- .../Scenes/Tests/SceneObjectLinkingTests.cs | 4 +-- 6 files changed, 58 insertions(+), 42 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 241cac0..916148b 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -111,11 +111,11 @@ namespace OpenSim.Region.Framework.Scenes private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) { - m_log.Debug("[SCENE]: Starting send to inventory loop"); + m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop"); while (InventoryDeQueueAndDelete()) { - //m_log.Debug("[SCENE]: Sent item successfully to inventory, continuing..."); + //m_log.Debug("[ASYNC DELETER]: Sent item successfully to inventory, continuing..."); } } @@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes x = m_inventoryDeletes.Dequeue(); m_log.DebugFormat( - "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); + "[ASYNC DELETER]: Sending object to user's inventory, {0} item(s) remaining.", left); try { @@ -152,7 +152,8 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception e) { - m_log.DebugFormat("Exception background sending object: " + e); + m_log.ErrorFormat( + "[ASYNC DELETER]: Exception background sending object: {0}{1}", e.Message, e.StackTrace); } return true; @@ -164,12 +165,16 @@ namespace OpenSim.Region.Framework.Scenes // We can't put the object group details in here since the root part may have disappeared (which is where these sit). // FIXME: This needs to be fixed. m_log.ErrorFormat( - "[SCENE]: Queued sending of scene object to agent {0} {1} failed: {2}", - (x != null ? x.remoteClient.Name : "unavailable"), (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"), e.ToString()); + "[ASYNC DELETER]: Queued sending of scene object to agent {0} {1} failed: {2} {3}", + (x != null ? x.remoteClient.Name : "unavailable"), + (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"), + e.Message, + e.StackTrace); } - m_log.Debug("[SCENE]: No objects left in inventory send queue."); + m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue."); + return false; } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index e183f9d..6fd38e5 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs @@ -69,6 +69,7 @@ namespace OpenSim.Region.Framework.Scenes public bool IsDeleted { get { return m_isDeleted; } + set { m_isDeleted = value; } } protected bool m_isDeleted; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4e871d9..c49386a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1720,7 +1720,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void DeRezObject(IClientAPI remoteClient, uint localID, UUID groupID, DeRezAction action, UUID destinationID) { - DeRezObjects(remoteClient, new List() { localID} , groupID, action, destinationID); + DeRezObjects(remoteClient, new List() { localID }, groupID, action, destinationID); } public virtual void DeRezObjects(IClientAPI remoteClient, List localIDs, @@ -1757,11 +1757,6 @@ namespace OpenSim.Region.Framework.Scenes deleteIDs.Add(localID); deleteGroups.Add(grp); - // Force a database backup/update on this SceneObjectGroup - // So that we know the database is upto date, - // for when deleting the object from it - ForceSceneObjectBackup(grp); - if (remoteClient == null) { // Autoreturn has a null client. Nothing else does. So diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 183310d..82e7d76 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2092,7 +2092,7 @@ namespace OpenSim.Region.Framework.Scenes // rootPart.PhysActor = null; // } - if (UnlinkSceneObject(group.UUID, false)) + if (UnlinkSceneObject(group, false)) { EventManager.TriggerObjectBeingRemovedFromScene(group); EventManager.TriggerParcelPrimCountTainted(); @@ -2107,18 +2107,25 @@ namespace OpenSim.Region.Framework.Scenes /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the /// object itself is not destroyed. /// - /// Id of object. + /// The scene object. + /// If true, only deletes from scene, but keeps the object in the database. /// true if the object was in the scene, false if it was not - /// If true, only deletes from scene, but keeps object in database. - public bool UnlinkSceneObject(UUID uuid, bool softDelete) + public bool UnlinkSceneObject(SceneObjectGroup so, bool softDelete) { - if (m_sceneGraph.DeleteSceneObject(uuid, softDelete)) + if (m_sceneGraph.DeleteSceneObject(so.UUID, softDelete)) { if (!softDelete) { - m_storageManager.DataStore.RemoveObject(uuid, - m_regInfo.RegionID); + // Force a database update so that the scene object group ID is accurate. It's possible that the + // group has recently been delinked from another group but that this change has not been persisted + // to the DB. + ForceSceneObjectBackup(so); + so.DetachFromBackup(); + m_storageManager.DataStore.RemoveObject(so.UUID, m_regInfo.RegionID); } + + // We need to keep track of this state in case this group is still queued for further backup. + so.IsDeleted = true; return true; } @@ -2149,7 +2156,7 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception) { - m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border."); + m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); } return; } @@ -2166,7 +2173,7 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception) { - m_log.Warn("[DATABASE]: exception when trying to return the prim that crossed the border."); + m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); } return; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b8b3db5..09e3e0e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1226,16 +1226,16 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Delete this group from its scene and tell all the scene presences about that deletion. + /// Delete this group from its scene. /// - /// Broadcast deletions to all clients. + /// + /// This only handles the in-world consequences of deletion (e.g. any avatars sitting on it are forcibly stood + /// up and all avatars receive notification of its removal. Removal of the scene object from database backup + /// must be handled by the caller. + /// + /// If true then deletion is not broadcast to clients public void DeleteGroup(bool silent) { - // We need to keep track of this state in case this group is still queued for backup. - m_isDeleted = true; - - DetachFromBackup(); - lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) @@ -1381,10 +1381,18 @@ namespace OpenSim.Region.Framework.Scenes public virtual void ProcessBackup(IRegionDataStore datastore, bool forcedBackup) { if (!m_isBackedUp) + { +// m_log.DebugFormat( +// "[WATER WARS]: Ignoring backup of {0} {1} since object is not marked to be backed up", Name, UUID); return; + } if (IsDeleted || UUID == UUID.Zero) + { +// m_log.DebugFormat( +// "[WATER WARS]: Ignoring backup of {0} {1} since object is marked as already deleted", Name, UUID); return; + } // Since this is the top of the section of call stack for backing up a particular scene object, don't let // any exception propogate upwards. @@ -1420,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes if (HasGroupChanged) { // don't backup while it's selected or you're asking for changes mid stream. - if ((isTimeToPersist()) || (forcedBackup)) + if (isTimeToPersist() || forcedBackup) { m_log.DebugFormat( "[SCENE]: Storing {0}, {1} in {2}", @@ -1443,19 +1451,19 @@ namespace OpenSim.Region.Framework.Scenes backup_group = null; } - // else - // { - // m_log.DebugFormat( - // "[SCENE]: Did not update persistence of object {0} {1}, selected = {2}", - // Name, UUID, IsSelected); - // } +// else +// { +// m_log.DebugFormat( +// "[SCENE]: Did not update persistence of object {0} {1}, selected = {2}", +// Name, UUID, IsSelected); +// } } } catch (Exception e) { m_log.ErrorFormat( - "[SCENE]: Storing of {0}, {1} in {2} failed with exception {3}\n\t{4}", - Name, UUID, m_scene.RegionInfo.RegionName, e, e.StackTrace); + "[SCENE]: Storing of {0}, {1} in {2} failed with exception {3}{4}", + Name, UUID, m_scene.RegionInfo.RegionName, e.Message, e.StackTrace); } } @@ -2245,7 +2253,7 @@ namespace OpenSim.Region.Framework.Scenes } } - m_scene.UnlinkSceneObject(objectGroup.UUID, true); + m_scene.UnlinkSceneObject(objectGroup, true); objectGroup.m_isDeleted = true; lock (objectGroup.m_parts) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 93409fa..62761fb 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -303,11 +303,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// /// Test that a delink of a previously linked object is correctly persisted to the database /// - //[Test] + [Test] public void TestDelinkPersistence() { TestHelper.InMethod(); - //log4net.Config.XmlConfigurator.Configure(); + log4net.Config.XmlConfigurator.Configure(); TestScene scene = SceneSetupHelpers.SetupScene(); -- cgit v1.1 From 8fda08d858091fcc425bfa146a8b44899029ed01 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 7 Sep 2010 11:48:28 +0100 Subject: Make sure unlinked child prims get persisted --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e7175c5..dfb26b9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1632,6 +1632,11 @@ namespace OpenSim.Region.Framework.Scenes // Unlink all child parts from their groups // child.ParentGroup.DelinkFromGroup(child, true); + + // These are not in affected groups and will not be + // handled further. Do the honors here. + child.ParentGroup.HasGroupChanged = true; + child.ParentGroup.ScheduleGroupForFullUpdate(); } foreach (SceneObjectPart root in rootParts) -- cgit v1.1 From 9be1c0ff448d4ea650ca921937905653b4017d61 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 7 Sep 2010 14:41:13 -0700 Subject: * Cache null account responses in the SimianUserAccountServiceConnector to avoid repeated requests for missing avatar IDs * Updated to OpenMetaverse r3442 to fix a timezone issue with ExpiringCache --- OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index da8199d..5e491c2 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -75,7 +75,9 @@ namespace OpenSim.Region.Framework.Tests protected TaskInventoryItem CreateSOItem1(Scene scene, SceneObjectPart part) { - AssetNotecard nc = new AssetNotecard("Hello World!"); + AssetNotecard nc = new AssetNotecard(); + nc.BodyText = "Hello World!"; + nc.Encode(); UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); AssetBase ncAsset -- cgit v1.1