diff options
author | Teravus Ovares | 2008-05-21 21:22:56 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-05-21 21:22:56 +0000 |
commit | 5af108a029e5382f6a2f6d4d10b3d4de3a8f5245 (patch) | |
tree | 171813c4182af2849052281c1e941dec434e6815 | |
parent | implement in memory appearance cache for sqlite. This (diff) | |
download | opensim-SC-5af108a029e5382f6a2f6d4d10b3d4de3a8f5245.zip opensim-SC-5af108a029e5382f6a2f6d4d10b3d4de3a8f5245.tar.gz opensim-SC-5af108a029e5382f6a2f6d4d10b3d4de3a8f5245.tar.bz2 opensim-SC-5af108a029e5382f6a2f6d4d10b3d4de3a8f5245.tar.xz |
* This update causes the backup process to run in a separate thread.
* Concurrency issues are resolved because each object makes a memory-only copy of itself and backs up the copy.
* Because of the way this is done, the latest at the time of the backup gets backed up (no functionality change)
* You can move *thousands of objects at a time* and the sim doesn't freeze and wait for the backup to complete.
* This can be enhanced more by dedicating the thread as opposed to starting it when the backup process starts.
Diffstat (limited to '')
6 files changed, 85 insertions, 37 deletions
diff --git a/OpenSim/Region/Environment/Scenes/EventManager.cs b/OpenSim/Region/Environment/Scenes/EventManager.cs index 7ff9213..c6daa28 100644 --- a/OpenSim/Region/Environment/Scenes/EventManager.cs +++ b/OpenSim/Region/Environment/Scenes/EventManager.cs | |||
@@ -355,10 +355,16 @@ namespace OpenSim.Region.Environment.Scenes | |||
355 | public void TriggerOnBackup(IRegionDataStore dstore) | 355 | public void TriggerOnBackup(IRegionDataStore dstore) |
356 | { | 356 | { |
357 | handlerBackup = OnBackup; | 357 | handlerBackup = OnBackup; |
358 | if (handlerBackup != null) | 358 | Delegate[] items = OnBackup.GetInvocationList(); |
359 | foreach (OnBackupDelegate del in items) | ||
359 | { | 360 | { |
360 | handlerBackup(dstore); | 361 | if (del != null) |
362 | del(dstore); | ||
361 | } | 363 | } |
364 | //if (handlerBackup != null) | ||
365 | //{ | ||
366 | // handlerBackup(dstore); | ||
367 | //} | ||
362 | } | 368 | } |
363 | 369 | ||
364 | public void TriggerParcelPrimCountUpdate() | 370 | public void TriggerParcelPrimCountUpdate() |
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 62055d8..695cb88 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs | |||
@@ -1399,7 +1399,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1399 | { | 1399 | { |
1400 | if (m_parentScene.ExternalChecks.ExternalChecksCanDuplicateObject(originPrim.Children.Count, originPrim.UUID, AgentID, originPrim.AbsolutePosition)) | 1400 | if (m_parentScene.ExternalChecks.ExternalChecksCanDuplicateObject(originPrim.Children.Count, originPrim.UUID, AgentID, originPrim.AbsolutePosition)) |
1401 | { | 1401 | { |
1402 | SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID); | 1402 | SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID, true); |
1403 | copy.AbsolutePosition = copy.AbsolutePosition + offset; | 1403 | copy.AbsolutePosition = copy.AbsolutePosition + offset; |
1404 | copy.ResetIDs(); | 1404 | copy.ResetIDs(); |
1405 | 1405 | ||
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 56d114c..280e09a 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -58,6 +58,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
58 | public SynchronizeSceneHandler SynchronizeScene = null; | 58 | public SynchronizeSceneHandler SynchronizeScene = null; |
59 | public int splitID = 0; | 59 | public int splitID = 0; |
60 | 60 | ||
61 | |||
61 | #region Fields | 62 | #region Fields |
62 | 63 | ||
63 | protected Timer m_heartbeatTimer = new Timer(); | 64 | protected Timer m_heartbeatTimer = new Timer(); |
@@ -83,6 +84,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
83 | private int m_RestartTimerCounter; | 84 | private int m_RestartTimerCounter; |
84 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 85 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
85 | private int m_incrementsof15seconds = 0; | 86 | private int m_incrementsof15seconds = 0; |
87 | private bool m_backingup = false; | ||
86 | 88 | ||
87 | public string m_simulatorVersion = "OpenSimulator 0.5"; | 89 | public string m_simulatorVersion = "OpenSimulator 0.5"; |
88 | 90 | ||
@@ -842,7 +844,14 @@ namespace OpenSim.Region.Environment.Scenes | |||
842 | 844 | ||
843 | private void UpdateStorageBackup() | 845 | private void UpdateStorageBackup() |
844 | { | 846 | { |
845 | Backup(); | 847 | if (!m_backingup) |
848 | { | ||
849 | m_backingup = true; | ||
850 | Thread backupthread = new Thread(Backup); | ||
851 | backupthread.Name = "BackupWriter"; | ||
852 | backupthread.IsBackground = true; | ||
853 | backupthread.Start(); | ||
854 | } | ||
846 | } | 855 | } |
847 | 856 | ||
848 | private void UpdateEvents() | 857 | private void UpdateEvents() |
@@ -863,10 +872,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
863 | /// | 872 | /// |
864 | /// </summary> | 873 | /// </summary> |
865 | /// <returns></returns> | 874 | /// <returns></returns> |
866 | public bool Backup() | 875 | public void Backup() |
867 | { | 876 | { |
868 | EventManager.TriggerOnBackup(m_storageManager.DataStore); | 877 | EventManager.TriggerOnBackup(m_storageManager.DataStore); |
869 | return true; | 878 | m_backingup = false; |
879 | //return true; | ||
870 | } | 880 | } |
871 | 881 | ||
872 | #endregion | 882 | #endregion |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 44e4c81..4b82bf9 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | |||
@@ -1085,13 +1085,24 @@ namespace OpenSim.Region.Environment.Scenes | |||
1085 | /// <param name="datastore"></param> | 1085 | /// <param name="datastore"></param> |
1086 | public void ProcessBackup(IRegionDataStore datastore) | 1086 | public void ProcessBackup(IRegionDataStore datastore) |
1087 | { | 1087 | { |
1088 | if (HasGroupChanged) | 1088 | // don't backup while it's selected or you're asking for changes mid stream. |
1089 | if (HasGroupChanged && !IsSelected) | ||
1089 | { | 1090 | { |
1090 | datastore.StoreObject(this, m_scene.RegionInfo.RegionID); | 1091 | m_log.Info("STORING"); |
1092 | SceneObjectGroup backup_group = Copy(OwnerID, GroupID, false); | ||
1093 | |||
1094 | datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); | ||
1091 | HasGroupChanged = false; | 1095 | HasGroupChanged = false; |
1096 | |||
1097 | backup_group.ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); }); | ||
1098 | |||
1099 | backup_group = null; | ||
1092 | } | 1100 | } |
1101 | |||
1102 | // Why is storing the inventory outside of HasGroupChanged? | ||
1093 | 1103 | ||
1094 | ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); }); | 1104 | |
1105 | //ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); }); | ||
1095 | } | 1106 | } |
1096 | 1107 | ||
1097 | #endregion | 1108 | #endregion |
@@ -1165,7 +1176,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1165 | /// Duplicates this object, including operations such as physics set up and attaching to the backup event. | 1176 | /// Duplicates this object, including operations such as physics set up and attaching to the backup event. |
1166 | /// </summary> | 1177 | /// </summary> |
1167 | /// <returns></returns> | 1178 | /// <returns></returns> |
1168 | public SceneObjectGroup Copy(LLUUID cAgentID, LLUUID cGroupID) | 1179 | public SceneObjectGroup Copy(LLUUID cAgentID, LLUUID cGroupID, bool userExposed) |
1169 | { | 1180 | { |
1170 | SceneObjectGroup dupe = (SceneObjectGroup) MemberwiseClone(); | 1181 | SceneObjectGroup dupe = (SceneObjectGroup) MemberwiseClone(); |
1171 | dupe.m_parts = new Dictionary<LLUUID, SceneObjectPart>(); | 1182 | dupe.m_parts = new Dictionary<LLUUID, SceneObjectPart>(); |
@@ -1176,11 +1187,13 @@ namespace OpenSim.Region.Environment.Scenes | |||
1176 | dupe.m_scene = m_scene; | 1187 | dupe.m_scene = m_scene; |
1177 | dupe.m_regionHandle = m_regionHandle; | 1188 | dupe.m_regionHandle = m_regionHandle; |
1178 | 1189 | ||
1179 | dupe.CopyRootPart(m_rootPart, OwnerID, GroupID); | 1190 | dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); |
1180 | dupe.m_rootPart.TrimPermissions(); | 1191 | |
1192 | if (userExposed) | ||
1193 | dupe.m_rootPart.TrimPermissions(); | ||
1181 | 1194 | ||
1182 | /// may need to create a new Physics actor. | 1195 | /// may need to create a new Physics actor. |
1183 | if (dupe.RootPart.PhysActor != null) | 1196 | if (dupe.RootPart.PhysActor != null && userExposed) |
1184 | { | 1197 | { |
1185 | PrimitiveBaseShape pbs = dupe.RootPart.Shape; | 1198 | PrimitiveBaseShape pbs = dupe.RootPart.Shape; |
1186 | 1199 | ||
@@ -1202,26 +1215,36 @@ namespace OpenSim.Region.Environment.Scenes | |||
1202 | // switch the owner to the person who did the copying | 1215 | // switch the owner to the person who did the copying |
1203 | // Second Life copies an object and duplicates the first one in it's place | 1216 | // Second Life copies an object and duplicates the first one in it's place |
1204 | // So, we have to make a copy of this one, set it in it's place then set the owner on this one | 1217 | // So, we have to make a copy of this one, set it in it's place then set the owner on this one |
1218 | if (userExposed) | ||
1219 | { | ||
1220 | SetRootPartOwner(m_rootPart, cAgentID, cGroupID); | ||
1221 | m_rootPart.ScheduleFullUpdate(); | ||
1222 | } | ||
1205 | 1223 | ||
1206 | SetRootPartOwner(m_rootPart, cAgentID, cGroupID); | 1224 | |
1207 | |||
1208 | |||
1209 | m_rootPart.ScheduleFullUpdate(); | ||
1210 | 1225 | ||
1211 | List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.Values); | 1226 | List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.Values); |
1212 | foreach (SceneObjectPart part in partList) | 1227 | foreach (SceneObjectPart part in partList) |
1213 | { | 1228 | { |
1214 | if (part.UUID != m_rootPart.UUID) | 1229 | if (part.UUID != m_rootPart.UUID) |
1215 | { | 1230 | { |
1216 | dupe.CopyPart(part, OwnerID, GroupID); | 1231 | dupe.CopyPart(part, OwnerID, GroupID, userExposed); |
1217 | SetPartOwner(part, cAgentID, cGroupID); | 1232 | |
1218 | part.ScheduleFullUpdate(); | 1233 | if (userExposed) |
1234 | { | ||
1235 | SetPartOwner(part, cAgentID, cGroupID); | ||
1236 | part.ScheduleFullUpdate(); | ||
1237 | } | ||
1219 | } | 1238 | } |
1220 | } | 1239 | } |
1221 | dupe.UpdateParentIDs(); | ||
1222 | 1240 | ||
1223 | dupe.AttachToBackup(); | 1241 | if (userExposed) |
1224 | ScheduleGroupForFullUpdate(); | 1242 | { |
1243 | dupe.UpdateParentIDs(); | ||
1244 | |||
1245 | dupe.AttachToBackup(); | ||
1246 | ScheduleGroupForFullUpdate(); | ||
1247 | } | ||
1225 | 1248 | ||
1226 | return dupe; | 1249 | return dupe; |
1227 | } | 1250 | } |
@@ -1232,9 +1255,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1232 | /// <param name="part"></param> | 1255 | /// <param name="part"></param> |
1233 | /// <param name="cAgentID"></param> | 1256 | /// <param name="cAgentID"></param> |
1234 | /// <param name="cGroupID"></param> | 1257 | /// <param name="cGroupID"></param> |
1235 | public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID) | 1258 | public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID, bool userExposed) |
1236 | { | 1259 | { |
1237 | SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count); | 1260 | SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count, userExposed); |
1238 | newPart.SetParent(this); | 1261 | newPart.SetParent(this); |
1239 | 1262 | ||
1240 | lock (m_parts) | 1263 | lock (m_parts) |
@@ -1364,9 +1387,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
1364 | /// <param name="part"></param> | 1387 | /// <param name="part"></param> |
1365 | /// <param name="cAgentID"></param> | 1388 | /// <param name="cAgentID"></param> |
1366 | /// <param name="cGroupID"></param> | 1389 | /// <param name="cGroupID"></param> |
1367 | public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID) | 1390 | public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID, bool userExposed) |
1368 | { | 1391 | { |
1369 | SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count); | 1392 | SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count, userExposed); |
1370 | newPart.SetParent(this); | 1393 | newPart.SetParent(this); |
1371 | 1394 | ||
1372 | lock (m_parts) | 1395 | lock (m_parts) |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs index d63260d..51521ff 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs | |||
@@ -99,7 +99,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
99 | } | 99 | } |
100 | 100 | ||
101 | HasInventoryChanged = true; | 101 | HasInventoryChanged = true; |
102 | 102 | ParentGroup.HasGroupChanged = true; | |
103 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values); | 103 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values); |
104 | TaskInventory.Clear(); | 104 | TaskInventory.Clear(); |
105 | 105 | ||
@@ -121,7 +121,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
121 | } | 121 | } |
122 | 122 | ||
123 | HasInventoryChanged = true; | 123 | HasInventoryChanged = true; |
124 | 124 | ParentGroup.HasGroupChanged = true; | |
125 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values); | 125 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values); |
126 | foreach (TaskInventoryItem item in items) | 126 | foreach (TaskInventoryItem item in items) |
127 | { | 127 | { |
@@ -304,6 +304,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
304 | m_inventorySerial++; | 304 | m_inventorySerial++; |
305 | //m_inventorySerial += 2; | 305 | //m_inventorySerial += 2; |
306 | HasInventoryChanged = true; | 306 | HasInventoryChanged = true; |
307 | ParentGroup.HasGroupChanged = true; | ||
307 | } | 308 | } |
308 | 309 | ||
309 | /// <summary> | 310 | /// <summary> |
@@ -373,6 +374,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
373 | TriggerScriptChangedEvent(Changed.INVENTORY); | 374 | TriggerScriptChangedEvent(Changed.INVENTORY); |
374 | 375 | ||
375 | HasInventoryChanged = true; | 376 | HasInventoryChanged = true; |
377 | ParentGroup.HasGroupChanged = true; | ||
376 | 378 | ||
377 | return true; | 379 | return true; |
378 | } | 380 | } |
@@ -411,6 +413,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
411 | TriggerScriptChangedEvent(Changed.INVENTORY); | 413 | TriggerScriptChangedEvent(Changed.INVENTORY); |
412 | 414 | ||
413 | HasInventoryChanged = true; | 415 | HasInventoryChanged = true; |
416 | ParentGroup.HasGroupChanged = true; | ||
414 | 417 | ||
415 | int scriptcount = 0; | 418 | int scriptcount = 0; |
416 | lock (m_taskInventory) | 419 | lock (m_taskInventory) |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index f5d3618..d95143e 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | |||
@@ -1523,12 +1523,14 @@ namespace OpenSim.Region.Environment.Scenes | |||
1523 | /// Duplicates this part. | 1523 | /// Duplicates this part. |
1524 | /// </summary> | 1524 | /// </summary> |
1525 | /// <returns></returns> | 1525 | /// <returns></returns> |
1526 | public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum) | 1526 | public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum, bool userExposed) |
1527 | { | 1527 | { |
1528 | SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone(); | 1528 | SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone(); |
1529 | dupe.m_shape = m_shape.Copy(); | 1529 | dupe.m_shape = m_shape.Copy(); |
1530 | dupe.m_regionHandle = m_regionHandle; | 1530 | dupe.m_regionHandle = m_regionHandle; |
1531 | dupe.UUID = LLUUID.Random(); | 1531 | if (userExposed) |
1532 | dupe.UUID = LLUUID.Random(); | ||
1533 | |||
1532 | dupe.LocalId = localID; | 1534 | dupe.LocalId = localID; |
1533 | dupe.OwnerID = AgentID; | 1535 | dupe.OwnerID = AgentID; |
1534 | dupe.GroupID = GroupID; | 1536 | dupe.GroupID = GroupID; |
@@ -1548,7 +1550,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
1548 | 1550 | ||
1549 | dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone(); | 1551 | dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone(); |
1550 | 1552 | ||
1551 | dupe.ResetIDs(linkNum); | 1553 | if (userExposed) |
1554 | dupe.ResetIDs(linkNum); | ||
1552 | 1555 | ||
1553 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. | 1556 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. |
1554 | dupe.LastOwnerID = ObjectOwner; | 1557 | dupe.LastOwnerID = ObjectOwner; |
@@ -1556,13 +1559,16 @@ namespace OpenSim.Region.Environment.Scenes | |||
1556 | byte[] extraP = new byte[Shape.ExtraParams.Length]; | 1559 | byte[] extraP = new byte[Shape.ExtraParams.Length]; |
1557 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 1560 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
1558 | dupe.Shape.ExtraParams = extraP; | 1561 | dupe.Shape.ExtraParams = extraP; |
1559 | if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero) | 1562 | |
1563 | if (userExposed) | ||
1560 | { | 1564 | { |
1561 | m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true); | 1565 | if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero) |
1566 | { | ||
1567 | m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true); | ||
1568 | } | ||
1569 | bool UsePhysics = ((dupe.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); | ||
1570 | dupe.DoPhysicsPropertyUpdate(UsePhysics, true); | ||
1562 | } | 1571 | } |
1563 | bool UsePhysics = ((dupe.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0); | ||
1564 | dupe.DoPhysicsPropertyUpdate(UsePhysics, true); | ||
1565 | |||
1566 | return dupe; | 1572 | return dupe; |
1567 | } | 1573 | } |
1568 | 1574 | ||