Added code to send out DelinkObject message at the actor that initiates the operation.

dsg
Huaiyu (Kitty) Liu 2011-01-27 16:19:36 -08:00
parent 270f7e653a
commit 1b99c33e6c
7 changed files with 118 additions and 13 deletions

View File

@ -379,6 +379,44 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
SendObjectUpdateToRelevantSyncConnectors(linkedGroup, rsm); SendObjectUpdateToRelevantSyncConnectors(linkedGroup, rsm);
} }
public void SendDeLinkObject(List<SceneObjectPart> prims, List<SceneObjectGroup> beforeDelinkGroups, List<SceneObjectGroup> afterDelinkGroups)
{
if (prims.Count==0 || beforeDelinkGroups.Count==0) return;
OSDMap data = new OSDMap();
data["partCount"] = OSD.FromInteger(prims.Count);
int partNum = 0;
foreach (SceneObjectPart part in prims)
{
string partTempID = "part" + partNum;
data[partTempID] = OSD.FromUUID(part.UUID);
partNum++;
}
//We also include the IDs of beforeDelinkGroups, for now it is more for sanity checking at the receiving end, so that the receiver
//could make sure its delink starts with the same linking state of the groups/prims.
data["beforeGroupsCount"] = OSD.FromInteger(beforeDelinkGroups.Count);
int groupNum = 0;
foreach (SceneObjectGroup affectedGroup in beforeDelinkGroups)
{
string groupTempID = "beforeGroup" + groupNum;
data[groupTempID] = OSD.FromUUID(affectedGroup.UUID);
groupNum++;
}
//include the property values of each object after delinking, for synchronizing the values
data["afterGroupsCount"] = OSD.FromInteger(beforeDelinkGroups.Count);
groupNum = 0;
foreach (SceneObjectGroup afterGroup in afterDelinkGroups)
{
string groupTempID = "afterGroup" + groupNum;
string sogxml = SceneObjectSerializer.ToXml2Format(afterGroup);
data[groupTempID] = OSD.FromString(sogxml);
groupNum++;
}
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.DelinkObject, OSDParser.SerializeJsonString(data));
SendDelinkObjectToRelevantSyncConnectors(beforeDelinkGroups, rsm);
}
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs) public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
{ {
@ -558,6 +596,25 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
private void SendDelinkObjectToRelevantSyncConnectors(List<SceneObjectGroup> beforeDelinkGroups, SymmetricSyncMessage syncMsg)
{
HashSet<int> syncConnectorsSent = new HashSet<int>();
foreach (SceneObjectGroup sog in beforeDelinkGroups)
{
List<SyncConnector> syncConnectors = GetSyncConnectorsForObjectUpdates(sog);
foreach (SyncConnector connector in syncConnectors)
{
if (!syncConnectorsSent.Contains(connector.ConnectorNum))
{
m_log.Debug(LogHeader + " send DeLinkObject to " + connector.Description);
connector.EnqueueOutgoingUpdate(sog.UUID, syncMsg.ToBytes());
syncConnectorsSent.Add(connector.ConnectorNum);
}
}
}
}
//Events are send out right away, without being put into the connector's outQueue first. //Events are send out right away, without being put into the connector's outQueue first.
//May need a better method for managing the outgoing messages (i.e. prioritizing object updates and events) //May need a better method for managing the outgoing messages (i.e. prioritizing object updates and events)
private void SendSceneEventToRelevantSyncConnectors(string init_actorID, SymmetricSyncMessage rsm) private void SendSceneEventToRelevantSyncConnectors(string init_actorID, SymmetricSyncMessage rsm)

View File

@ -31,6 +31,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
UpdatedObject, // objects UpdatedObject, // objects
RemovedObject, // objects RemovedObject, // objects
LinkObject, LinkObject,
DelinkObject,
RegionName, RegionName,
//RegionStatus, //RegionStatus,
ActorID, ActorID,

View File

@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
if (m_syncOtherSideRegionName == null) if (m_syncOtherSideRegionName == null)
return String.Format("SyncConnector #{0}", m_connectorNum); return String.Format("SyncConnector #{0}", m_connectorNum);
return String.Format("SyncConnector #{0} ({1:10})", m_connectorNum, m_syncOtherSideRegionName); return String.Format("SyncConnector #{0} (Actor {2}, Region {1:10})", m_connectorNum, m_syncOtherSideRegionName, m_syncOtherSideActorID);
} }
} }

View File

@ -60,16 +60,16 @@ namespace OpenSim.Region.Framework.Interfaces
void QueueSceneObjectPartForUpdate(SceneObjectPart part); void QueueSceneObjectPartForUpdate(SceneObjectPart part);
void QueueScenePresenceForTerseUpdate(ScenePresence presence); void QueueScenePresenceForTerseUpdate(ScenePresence presence);
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector //The folloiwng calls deal with object updates, and will insert each update into an outgoing queue of each SyncConnector
void SendSceneUpdates(); void SendSceneUpdates();
void SendDeleteObject(SceneObjectGroup sog, bool softDelete);
void SendLinkObject(SceneObjectGroup linkedGroup, SceneObjectPart root, List<SceneObjectPart> children);
void SendDeLinkObject(List<SceneObjectPart> prims, List<SceneObjectGroup> beforeDelinkGroups, List<SceneObjectGroup> afterDelinkGroups);
//In RegionSyncModule's implementation, //In RegionSyncModule's implementation,
//The following calls send out a message immediately, w/o putting it in the SyncConnector's outgoing queue. //The following calls send out a message immediately, w/o putting it in the SyncConnector's outgoing queue.
//May need some optimization there on the priorities. //May need some optimization there on the priorities.
void SendTerrainUpdates(string lastUpdateActorID); void SendTerrainUpdates(string lastUpdateActorID);
void SendDeleteObject(SceneObjectGroup sog, bool softDelete);
void SendLinkObject(SceneObjectGroup linkedGroup, SceneObjectPart root, List<SceneObjectPart> children);
//For propogating scene events to other actors //For propogating scene events to other actors
void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs); void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs);

View File

@ -1598,13 +1598,14 @@ namespace OpenSim.Region.Framework.Scenes
//so should return quickly. //so should return quickly.
if (m_parentScene.RegionSyncModule != null) if (m_parentScene.RegionSyncModule != null)
{ {
//Tell other actors to link the SceneObjectParts together as a new group. But not updating the properties yet. //Tell other actors to link the SceneObjectParts together as a new group.
//The properties will be updated later when parentGroup.ScheduleGroupForFullUpdate() is called below.
parentGroup.SyncInfoUpdate(); parentGroup.SyncInfoUpdate();
m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children); m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children);
} }
//Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers) //Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers).
//But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them
//via the LinkObject message sent above.
parentGroup.ScheduleGroupForFullUpdate_SyncInfoUnchanged(); parentGroup.ScheduleGroupForFullUpdate_SyncInfoUnchanged();
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC
@ -1628,6 +1629,11 @@ namespace OpenSim.Region.Framework.Scenes
List<SceneObjectPart> childParts = new List<SceneObjectPart>(); List<SceneObjectPart> childParts = new List<SceneObjectPart>();
List<SceneObjectPart> rootParts = new List<SceneObjectPart>(); List<SceneObjectPart> rootParts = new List<SceneObjectPart>();
List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>(); List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>();
//SYMMETRIC SYNC, record the new object groups after the delink operation
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
// Look them all up in one go, since that is comparatively expensive // Look them all up in one go, since that is comparatively expensive
// //
foreach (SceneObjectPart part in prims) foreach (SceneObjectPart part in prims)
@ -1643,7 +1649,11 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup group = part.ParentGroup; SceneObjectGroup group = part.ParentGroup;
if (!affectedGroups.Contains(group)) if (!affectedGroups.Contains(group))
{
affectedGroups.Add(group); affectedGroups.Add(group);
//SYMMETRIC SYNC
beforeDelinkGroups.Add(group);
}
} }
} }
} }
@ -1657,7 +1667,10 @@ namespace OpenSim.Region.Framework.Scenes
// These are not in affected groups and will not be // These are not in affected groups and will not be
// handled further. Do the honors here. // handled further. Do the honors here.
child.ParentGroup.HasGroupChanged = true; child.ParentGroup.HasGroupChanged = true;
child.ParentGroup.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC, delay ScheduleGroupForFullUpdate till the end of the delink operations.
//child.ParentGroup.ScheduleGroupForFullUpdate();
afterDelinkGroups.Add(child.ParentGroup);
} }
foreach (SceneObjectPart root in rootParts) foreach (SceneObjectPart root in rootParts)
@ -1726,8 +1739,34 @@ namespace OpenSim.Region.Framework.Scenes
{ {
g.TriggerScriptChangedEvent(Changed.LINK); g.TriggerScriptChangedEvent(Changed.LINK);
g.HasGroupChanged = true; // Persist g.HasGroupChanged = true; // Persist
g.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC, delay ScheduleGroupForFullUpdate till the end of the delink operations.
//g.ScheduleGroupForFullUpdate();
afterDelinkGroups.Add(g);
} }
//SYMMETRIC SYNC
//set timestamp
long timeStamp = DateTime.Now.Ticks;
string actorID = m_parentScene.GetSyncActorID();
foreach (SceneObjectGroup sog in afterDelinkGroups)
{
if (m_parentScene.RegionSyncModule != null)
{
sog.SyncInfoUpdate(timeStamp, actorID); ;
}
}
//Send out DelinkObject message to other actors to sychronize their object list
m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups);
//Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers).
//But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them
foreach (SceneObjectGroup sog in afterDelinkGroups)
{
sog.ScheduleGroupForFullUpdate_SyncInfoUnchanged();
}
//end of SYMMETRIC SYNC
} }
finally finally
{ {

View File

@ -3862,7 +3862,15 @@ namespace OpenSim.Region.Framework.Scenes
public void SyncInfoUpdate() public void SyncInfoUpdate()
{ {
long timeStamp = DateTime.Now.Ticks; long timeStamp = DateTime.Now.Ticks;
string actorID = m_scene.ActorSyncModule.ActorID; string actorID = m_scene.GetSyncActorID();
foreach (SceneObjectPart part in Parts)
{
part.SyncInfoUpdate(timeStamp, actorID);
}
}
public void SyncInfoUpdate(long timeStamp, string actorID)
{
foreach (SceneObjectPart part in Parts) foreach (SceneObjectPart part in Parts)
{ {
part.SyncInfoUpdate(timeStamp, actorID); part.SyncInfoUpdate(timeStamp, actorID);

View File

@ -4940,7 +4940,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (m_parentGroup != null) if (m_parentGroup != null)
{ {
m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID; m_lastUpdateActorID = m_parentGroup.Scene.GetSyncActorID();
} }
else else
{ {
@ -4967,7 +4967,7 @@ namespace OpenSim.Region.Framework.Scenes
// ScheduleFullUpdate() is called when m_parentGroup == null // ScheduleFullUpdate() is called when m_parentGroup == null
if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.ActorSyncModule != null) if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.ActorSyncModule != null)
{ {
SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.ActorSyncModule.ActorID); SyncInfoUpdate(DateTime.Now.Ticks, m_parentGroup.Scene.GetSyncActorID());
} }
} }