diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index f6060184fa..eb9d509e16 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -62,6 +62,9 @@ namespace OpenSim.Region.Environment.Scenes public SynchronizeSceneHandler SynchronizeScene = null; public int splitID = 0; + private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; + private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; + #region Fields protected Timer m_restartWaitTimer = new Timer(); @@ -171,6 +174,11 @@ namespace OpenSim.Region.Environment.Scenes private object m_deleting_scene_object = new object(); + // the minimum time that must elapse before a changed object will be considered for persisted + public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L; + // the maximum time that must elapse before a changed object will be considered for persisted + public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L; + #endregion #region Properties @@ -335,6 +343,12 @@ namespace OpenSim.Region.Environment.Scenes m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", 65536.0f); m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", 10.0f); m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", false); + m_dontPersistBefore = + startupConfig.GetInt("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE); + m_dontPersistBefore *= 10000000; + m_persistAfter = + startupConfig.GetInt("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE); + m_persistAfter *= 10000000; m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); } @@ -348,6 +362,11 @@ namespace OpenSim.Region.Environment.Scenes #region Startup / Close Methods + public bool ShuttingDown + { + get { return shuttingdown; } + } + protected virtual void RegisterDefaultSceneEvents() { m_eventManager.OnPermissionError += SendPermissionAlert; diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index c51f235e21..d929be228d 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -92,7 +92,39 @@ namespace OpenSim.Region.Environment.Scenes /// Signal whether the non-inventory attributes of any prims in the group have changed /// since the group's last persistent backup /// - public bool HasGroupChanged = false; + private bool m_hasGroupChanged = false; + private long timeFirstChanged; + private long timeLastChanged; + + public bool HasGroupChanged + { + set + { + if (value) + { + timeLastChanged = DateTime.Now.Ticks; + if (!m_hasGroupChanged) + timeFirstChanged = DateTime.Now.Ticks; + } + m_hasGroupChanged = value; + } + + get { return m_hasGroupChanged; } + } + + private bool isTimeToPersist() + { + if (IsSelected || IsDeleted || IsAttachment) + return false; + if (!m_hasGroupChanged) + return false; + if (m_scene.ShuttingDown) + return true; + long currentTime = DateTime.Now.Ticks; + if (currentTime - timeLastChanged > m_scene.m_dontPersistBefore || currentTime - timeFirstChanged > m_scene.m_persistAfter) + return true; + return false; + } /// /// Is this scene object acting as an attachment? @@ -1190,25 +1222,28 @@ namespace OpenSim.Region.Environment.Scenes try { - ILandObject parcel = m_scene.LandChannel.GetLandObject( - m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); - - if (parcel != null && parcel.landData != null && - parcel.landData.OtherCleanTime != 0) + if (!m_scene.ShuttingDown) // if shutting down then there will be nothing to handle the return so leave till next restart { - if (parcel.landData.OwnerID != OwnerID && - (parcel.landData.GroupID != GroupID || - parcel.landData.GroupID == UUID.Zero)) - { - if ((DateTime.Now - RootPart.Rezzed).TotalMinutes > - parcel.landData.OtherCleanTime) - { - m_log.InfoFormat("[SCENE] Returning object {0} due to parcel auto return", RootPart.UUID.ToString()); - m_scene.AddReturn(OwnerID, Name, AbsolutePosition); - m_scene.DeRezObject(null, RootPart.LocalId, - RootPart.GroupID, 9, UUID.Zero); + ILandObject parcel = m_scene.LandChannel.GetLandObject( + m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); - return; + if (parcel != null && parcel.landData != null && + parcel.landData.OtherCleanTime != 0) + { + if (parcel.landData.OwnerID != OwnerID && + (parcel.landData.GroupID != GroupID || + parcel.landData.GroupID == UUID.Zero)) + { + if ((DateTime.Now - RootPart.Rezzed).TotalMinutes > + parcel.landData.OtherCleanTime) + { + m_log.InfoFormat("[SCENE] Returning object {0} due to parcel auto return", RootPart.UUID.ToString()); + m_scene.AddReturn(OwnerID, Name, AbsolutePosition); + m_scene.DeRezObject(null, RootPart.LocalId, + RootPart.GroupID, 9, UUID.Zero); + + return; + } } } } @@ -1216,7 +1251,7 @@ namespace OpenSim.Region.Environment.Scenes if (HasGroupChanged) { // don't backup while it's selected or you're asking for changes mid stream. - if (!(IsSelected || IsDeleted || IsAttachment)) + if (isTimeToPersist()) { m_log.DebugFormat( "[SCENE]: Storing {0}, {1} in {2}", @@ -1227,9 +1262,9 @@ namespace OpenSim.Region.Environment.Scenes backup_group.RootPart.Acceleration = RootPart.Acceleration; backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; + HasGroupChanged = false; datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); - HasGroupChanged = false; backup_group.ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); }); diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 7b61790e83..1464bee73b 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -79,6 +79,15 @@ asset_database = "local" ;asset_database = "grid" + ; Persistence of changed objects happens during regular sweeps. The following control that behaviour to + ; prevent frequently changing objects from heavily loading the region data store. + ; If both of these values are set to zero then persistence of all changed objects will happen on every sweep. + ; + ; Objects will be considered for persistance in the next sweep when they have not changed for this number of seconds + MinimumTimeBeforePersistenceConsidered = 60 + ; Objects will always be considered for persistance in the next sweep if the first change occurred this number of seconds ago + MaximumTimeBeforePersistenceConsidered = 600 + ; Should avatars in neighbor sims see objects in this sim? see_into_this_sim_from_neighbor = True