No longer calling SyncInfoUpdate to update timestamp. Bucket based concurrency control now in place for a few physics properties

whose SetXXX() functions have been implemented in SceneObjectPart.
dsg
Huaiyu (Kitty) Liu 2011-02-03 17:21:00 -08:00
parent 3cff68340f
commit 62a9e0b7c4
7 changed files with 153 additions and 45 deletions

View File

@ -262,7 +262,22 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void QueueSceneObjectPartForUpdate(SceneObjectPart part)
{
//if the last update of the prim is caused by this actor itself, or if the actor is a relay node, then enqueue the update
if (part.LastUpdateActorID.Equals(m_actorID) || m_isSyncRelay)
//if (part.LastUpdateActorID.Equals(m_actorID) || m_isSyncRelay)
bool updated = m_isSyncRelay;
if (!updated)
{
foreach (KeyValuePair<string, BucketSyncInfo> pair in part.BucketSyncInfoList)
{
if (pair.Value.LastUpdateActorID.Equals(m_actorID))
{
updated = true;
break;
}
}
}
if(updated)
{
lock (m_updateSceneObjectPartLock)
{
@ -273,10 +288,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void QueueScenePresenceForTerseUpdate(ScenePresence presence)
{
/*
lock (m_updateScenePresenceLock)
{
m_presenceUpdates[presence.UUID] = presence;
}
* */
}
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector
@ -740,7 +757,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
/// <summary>
/// Check if we need to send out an update message for the given object.
/// Check if we need to send out an update message for the given object. For now, we have a very inefficient solution:
/// If any synchronization bucket in any part shows a property in that bucket has changed, we'll serialize and ship the whole object.
/// </summary>
/// <param name="sog"></param>
/// <returns></returns>
@ -749,10 +767,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//If any part in the object has the last update caused by this actor itself, then send the update
foreach (SceneObjectPart part in sog.Parts)
{
/*
if (part.LastUpdateActorID.Equals(m_actorID))
{
return true;
}
* */
foreach (KeyValuePair<string, BucketSyncInfo> pair in part.BucketSyncInfoList)
{
if (pair.Value.LastUpdateActorID.Equals(m_actorID))
{
return true;
}
}
}
return false;
@ -840,7 +868,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
//Start symmetric synchronization initialization automatically
//SyncStart(null);
SyncStart(null);
}
private void StartLocalSyncListener()

View File

@ -1720,7 +1720,7 @@ namespace OpenSim.Region.Framework.Scenes
* */
if (RegionSyncModule != null)
{
part.SyncInfoUpdate();
//part.SyncInfoUpdate();
EventManager.TriggerNewScript(remoteClient.AgentId, part, copyID);
}
else
@ -1798,7 +1798,7 @@ namespace OpenSim.Region.Framework.Scenes
//part.ParentGroup.ResumeScripts();
if (RegionSyncModule != null)
{
part.SyncInfoUpdate();
//part.SyncInfoUpdate();
EventManager.TriggerNewScript(remoteClient.AgentId, part, taskItem.ItemID);
}
else

View File

@ -2560,16 +2560,6 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
//SYMMETRIC SYNC
//Set the ActorID and TimeStamp info for this latest update
/*
foreach (SceneObjectPart part in group.Parts)
{
part.SyncInfoUpdate();
}
*
* */
//Propagate the RemovedObject message
if (RegionSyncModule != null)
{

View File

@ -1599,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentScene.RegionSyncModule != null)
{
//Tell other actors to link the SceneObjectParts together as a new group.
parentGroup.SyncInfoUpdate();
//parentGroup.SyncInfoUpdate();
m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children);
}
@ -1747,6 +1747,7 @@ namespace OpenSim.Region.Framework.Scenes
//SYMMETRIC SYNC
//set timestamp
/*
long timeStamp = DateTime.Now.Ticks;
string actorID = m_parentScene.GetSyncActorID();
foreach (SceneObjectGroup sog in afterDelinkGroups)
@ -1756,6 +1757,7 @@ namespace OpenSim.Region.Framework.Scenes
sog.SyncInfoUpdate(timeStamp, actorID); ;
}
}
* */
//Send out DelinkObject message to other actors to sychronize their object list
m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups);
@ -2065,7 +2067,10 @@ namespace OpenSim.Region.Framework.Scenes
}
m_numPrim += children.Length;
//SYMMETRIC SYNC,
sceneObject.AttachToScene(m_parentScene);
//sceneObject.AttachToSceneBySync(m_parentScene);
//end of SYMMETRIC SYNC,
//SYMMETRIC SYNC,
sceneObject.ScheduleGroupForFullUpdate_SyncInfoUnchanged();

View File

@ -3868,6 +3868,7 @@ namespace OpenSim.Region.Framework.Scenes
}
/*
public void SyncInfoUpdate()
{
long timeStamp = DateTime.Now.Ticks;
@ -3885,6 +3886,46 @@ namespace OpenSim.Region.Framework.Scenes
part.SyncInfoUpdate(timeStamp, actorID);
}
}
* */
/// <summary>
/// Attach this object to a scene after a new object is created due to receiving a sync message.
/// Code similar to AttachToScene, except that this does not invoke InitializeBucketSyncInfo of each part,
/// as that information is included in the incoming message.
/// </summary>
/// <param name="scene"></param>
public void AttachToSceneBySync(Scene scene)
{
m_scene = scene;
RegionHandle = m_scene.RegionInfo.RegionHandle;
if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0)
m_rootPart.ParentID = 0;
if (m_rootPart.LocalId == 0)
m_rootPart.LocalId = m_scene.AllocateLocalId();
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (Object.ReferenceEquals(part, m_rootPart))
continue;
if (part.LocalId == 0)
part.LocalId = m_scene.AllocateLocalId();
part.ParentID = m_rootPart.LocalId;
//m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
}
ApplyPhysics(m_scene.m_physicalPrim);
// Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
// for the same object with very different properties. The caller must schedule the update.
//ScheduleGroupForFullUpdate();
}
#endregion
}

View File

@ -121,11 +121,13 @@ namespace OpenSim.Region.Framework.Scenes
public long LastUpdateTimeStamp
{
get { return m_lastUpdateTimeStamp; }
set { m_lastUpdateTimeStamp = value; }
}
public string LastUpdateActorID
{
get { return m_lastUpdateActorID; }
set { m_lastUpdateActorID = value; }
}
public string BucketName
@ -3131,7 +3133,7 @@ namespace OpenSim.Region.Framework.Scenes
//SYMMETRIC SYNC
//update information (timestamp, actorID, etc) needed for synchronization across copies of Scene
SyncInfoUpdate();
//SyncInfoUpdate();
//end of SYMMETRIC SYNC
}
@ -3159,7 +3161,7 @@ namespace OpenSim.Region.Framework.Scenes
//SYMMETRIC SYNC
//update information (timestamp, actorID, etc) needed for synchronization across copies of Scene
SyncInfoUpdate();
//SyncInfoUpdate();
//end of SYMMETRIC SYNC
}
@ -5158,6 +5160,7 @@ namespace OpenSim.Region.Framework.Scenes
//The ID the identifies which actor has caused the most recent update to the prim.
//We use type "string" for the ID only to make it human-readable.
/*
private string m_lastUpdateActorID="";
public string LastUpdateActorID
{
@ -5169,6 +5172,7 @@ namespace OpenSim.Region.Framework.Scenes
{
m_lastUpdateTimeStamp = time;
}
public void SetLastUpdateActorID()
{
@ -5182,17 +5186,19 @@ namespace OpenSim.Region.Framework.Scenes
}
}
private Object m_SyncInfoLock = new Object();
public void SyncInfoUpdate(long timeStamp, string actorID)
{
//update timestamp and actorID atomically
lock (m_SyncInfoLock)
{
UpdateTimestamp(timeStamp);
m_lastUpdateActorID = actorID;
}
}
public void SyncInfoUpdate()
{
@ -5204,6 +5210,7 @@ namespace OpenSim.Region.Framework.Scenes
SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.GetSyncActorID());
}
}
* */
//The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors.
//This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the
@ -5281,7 +5288,7 @@ namespace OpenSim.Region.Framework.Scenes
/*
private Object propertyUpdateLock = new Object();
//!!!!!! -- TODO:
@ -5410,6 +5417,8 @@ namespace OpenSim.Region.Framework.Scenes
return partUpdateResult;
}
* */
private bool UpdateCollisionSound(UUID updatedCollisionSound)
@ -5424,8 +5433,12 @@ namespace OpenSim.Region.Framework.Scenes
public string DebugObjectPartProperties()
{
string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId + ", lastUpdateActorID " + LastUpdateActorID + ", lastUpdateTimeStamp " + LastUpdateTimeStamp;
string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId;
debugMsg += ", parentID " + ParentID + ", parentUUID " + ParentUUID;
foreach (KeyValuePair<string, BucketSyncInfo> pair in m_bucketSyncInfoList)
{
debugMsg += ", Bucket " + pair.Key + ": TimeStamp - " + pair.Value.LastUpdateTimeStamp + ", ActorID - " + pair.Value.LastUpdateActorID;
}
return debugMsg;
}
@ -5484,9 +5497,10 @@ namespace OpenSim.Region.Framework.Scenes
private static string m_localActorID = "";
//private static int m_bucketCount = 0;
//private delegate void BucketUpdateProcessor(int bucketIndex);
private delegate void BucketUpdateProcessor(string bucketName);
private delegate void BucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName);
private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
//private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
private Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
public static void InitializeBucketInfo(Dictionary<string, string> propertyBucketMap, List<string> bucketNames, string actorID)
{
@ -5495,14 +5509,17 @@ namespace OpenSim.Region.Framework.Scenes
m_localActorID = actorID;
//m_bucketCount = bucketNames.Count;
RegisterBucketUpdateProcessor();
//RegisterBucketUpdateProcessor();
}
/// <summary>
/// Link each bucket with the function that applies updates to properties in the bucket. This is the "hard-coded" part
/// in the property-buckets implementation. When new buckets are implemented, the processing functions need to be modified accordingly.
/// Link each bucket with the function that applies updates to properties in the bucket upon receiving sync messages.
/// This is the "hard-coded" part in the property-buckets implementation. When new buckets are implemented,
/// the processing functions need to be modified accordingly.
/// </summary>
private static void RegisterBucketUpdateProcessor()
//private static void RegisterBucketUpdateProcessor()
private void RegisterBucketUpdateProcessor()
{
foreach (string bucketName in m_propertyBucketNames)
{
@ -5521,19 +5538,42 @@ namespace OpenSim.Region.Framework.Scenes
}
}
private static void GeneralBucketUpdateProcessor(string bucketName)
private void GeneralBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName)
{
lock (m_bucketUpdateLocks[bucketName])
{
m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp;
m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID;
}
}
private static void PhysicsBucketUpdateProcessor(string bucketName)
private void PhysicsBucketUpdateProcessor(SceneObjectPart updatedPart, string bucketName)
{
lock (m_bucketUpdateLocks[bucketName])
{
SetGroupPosition(updatedPart.GroupPosition);
SetOffsetPosition(updatedPart.OffsetPosition);
SetScale(updatedPart.Scale);
SetVelocity(updatedPart.Velocity);
SetAngularVelocity(updatedPart.AngularVelocity);
SetRotationOffset(updatedPart.RotationOffset);
//implementation in PhysicsActor
/*
"Position":
"Size":
"Force":
"RotationalVelocity":
"PA_Acceleration":
"Torque":
"Orientation":
"IsPhysical":
"Flying":
"Buoyancy":
* */
m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp;
m_bucketSyncInfoList[bucketName].LastUpdateActorID = updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID;
}
}
@ -5556,19 +5596,22 @@ namespace OpenSim.Region.Framework.Scenes
BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName);
//If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets
if (m_bucketSyncInfoList.ContainsKey(bucketName))
{
m_bucketSyncInfoList[bucketName] = syncInfo;
}
else
if (!m_bucketSyncInfoList.ContainsKey(bucketName))
//if (m_bucketSyncInfoList.ContainsKey(bucketName))
//{
// m_bucketSyncInfoList[bucketName] = syncInfo;
//}
//else
{
m_bucketSyncInfoList.Add(bucketName, syncInfo);
}
if (!m_bucketSyncInfoList.ContainsKey(bucketName))
if (!m_bucketUpdateLocks.ContainsKey(bucketName))
{
m_bucketUpdateLocks.Add(bucketName, new Object());
}
}
RegisterBucketUpdateProcessor();
}
/// <summary>
@ -5595,8 +5638,6 @@ namespace OpenSim.Region.Framework.Scenes
/*
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
{
@ -5616,7 +5657,8 @@ namespace OpenSim.Region.Framework.Scenes
Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged;
for (int i=0; i<m_bucketCount; i++){
for (int i = 0; i < m_propertyBucketNames.Count; i++)
{
string bucketName = m_propertyBucketNames[i];
//First, compare the bucket's timestamp and actorID
if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp > updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp)
@ -5638,7 +5680,7 @@ namespace OpenSim.Region.Framework.Scenes
//Second, if need to update local properties, call each bucket's update process
if (m_bucketUpdateProcessors.ContainsKey(bucketName))
{
m_bucketUpdateProcessors[bucketName](bucketName);
m_bucketUpdateProcessors[bucketName](updatedPart, bucketName);
partUpdateResult = Scene.ObjectUpdateResult.Updated;
}
else
@ -5652,7 +5694,7 @@ namespace OpenSim.Region.Framework.Scenes
return partUpdateResult;
}
*/
//private void UpdateBucketProperties(string bucketDescription,
#endregion

View File

@ -330,8 +330,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
//SYMMETRIC SYNC
m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
//m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
//m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo);
//end of SYMMETRIC SYNC
@ -703,6 +703,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
}
//SYMMETRIC SYNC
/*
private static void ProcessUpdateTimeStamp(SceneObjectPart obj, XmlTextReader reader)
{
obj.LastUpdateTimeStamp = reader.ReadElementContentAsLong("LastUpdateTimeStamp", string.Empty);
@ -712,6 +713,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
{
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
}
* */
public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader)
{
@ -1245,8 +1247,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
//SYMMETRIC SYNC
writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
//writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
//writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
WriteBucketSyncInfo(writer, sop.BucketSyncInfoList);
//end of SYMMETRIC SYNC