Added SymSync in config file. If SymSync = true, then code in the old sync module (asym sync) that handle object updates

are disabled. Then we effectively have new ways (RegionSyncModule) of handle object updates, and old ways of handling
avatar updates working together.
dsg
Huaiyu (Kitty) Liu 2011-01-04 10:12:35 -08:00
parent f5df61162f
commit d84e69fefe
6 changed files with 140 additions and 71 deletions

View File

@ -47,6 +47,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
Dictionary<UUID, RegionSyncAvatar> m_remoteAvatars = new Dictionary<UUID, RegionSyncAvatar>();
Dictionary<UUID, IClientAPI> m_localAvatars = new Dictionary<UUID, IClientAPI>();
private bool m_symSync = false;
private Dictionary<UUID, RegionSyncAvatar> RemoteAvatars
{
get { return m_remoteAvatars; }
@ -276,6 +278,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AvatarAppearance, OSDParser.SerializeJsonString(data)));
}
public void SetSymSync(bool symSync)
{
m_symSync = symSync;
}
// Handle an incoming message
// TODO: This should not be synchronous with the receive!
// Instead, handle messages from an incoming Queue so server doesn't block sending
@ -289,15 +296,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Syncing to region \"{0}\"", m_regionName));
return;
}
//SYMMETRIC SYNC: do not handle terrian and object updates
case RegionSyncMessage.MsgType.Terrain:
{
if(!m_symSync)
{
m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
RegionSyncMessage.HandleSuccess(LogHeader(), msg, "Synchronized terrain");
}
return;
}
case RegionSyncMessage.MsgType.NewObject:
case RegionSyncMessage.MsgType.UpdatedObject:
{
if(!m_symSync){
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
if (sog.IsDeleted)
{
@ -305,23 +317,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return;
}
/*
m_log.DebugFormat("{0} NewObject '{1}'", LogHeader(), sog.Name);
sog.ForEachPart(delegate(SceneObjectPart part)
{
m_log.DebugFormat("{0} Part {1}, lf={2} f={3}", LogHeader(), part.Name,
part.LocalFlags.ToString(), part.Flags.ToString());
});
*/
if (m_scene.AddNewSceneObject(sog, true));
//RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
//else
//RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
sog.ScheduleGroupForFullUpdate();
}
return;
}
case RegionSyncMessage.MsgType.RemovedObject:
{
if(!m_symSync)
{
// Get the data from message and error check
OSDMap data = DeserializeMessage(msg);
if (data == null)
@ -345,8 +352,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
// Delete the object from the scene
m_scene.DeleteSceneObject(sog, false);
RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("localID {0} deleted.", localID.ToString()));
}
return;
}
//end of SYMMETRIC SYNC
case RegionSyncMessage.MsgType.NewAvatar:
{
// Get the data from message and error check
@ -815,8 +824,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName));
m_log.WarnFormat("Sending region name: \"{0}\"", m_scene.RegionInfo.RegionName);
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain));
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects));
//SYMMETRIC SYNC: commenting out terrian and object updates
if (!m_symSync)
{
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain));
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects));
}
//end of SYMMETRIC SYNC
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetAvatars));
// Register for events which will be forwarded to authoritative scene

View File

@ -75,6 +75,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_serverport = syncConfig.GetInt(scene.RegionInfo.RegionName+"_ServerPort", serverPortDefault);
m_scene.RegisterModuleInterface<IRegionSyncClientModule>(this);
m_symsync = syncConfig.GetBoolean("SymSync", false);
// Setup the command line interface
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
InstallInterfaces();
@ -156,6 +158,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private Object m_client_lock = new Object();
private RegionSyncClient m_client = null;
private bool m_symsync = false;
#endregion
@ -239,6 +242,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_log.Warn("[REGION SYNC CLIENT MODULE] Starting RegionSyncClient");
m_client = new RegionSyncClient(m_scene, m_serveraddr, m_serverport);
m_client.SetSymSync(m_symsync);
m_client.Start();
}
}

View File

@ -302,26 +302,34 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_regionName));
return;
}
//SYMMETRIC SYNC: do not handle terrian and object updates
case RegionSyncMessage.MsgType.GetTerrain:
{
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()));
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Terrain sent");
if (!m_scene.RegionSyncServerModule.IsSymSync)
{
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()));
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Terrain sent");
}
return;
}
case RegionSyncMessage.MsgType.GetObjects:
{
EntityBase[] entities = m_scene.GetEntities();
foreach(EntityBase e in entities)
if (!m_scene.RegionSyncServerModule.IsSymSync)
{
if (e is SceneObjectGroup)
EntityBase[] entities = m_scene.GetEntities();
foreach (EntityBase e in entities)
{
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e);
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml));
if (e is SceneObjectGroup)
{
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e);
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml));
}
}
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Sent all scene objects");
}
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Sent all scene objects");
return;
}
//end of SYMMETRIC SYNC
case RegionSyncMessage.MsgType.GetAvatars:
{
m_scene.ForEachScenePresence(delegate(ScenePresence presence)

View File

@ -48,6 +48,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public class RegionSyncServerModule : IRegionModule, IRegionSyncServerModule, ICommandableModule
{
private static int DefaultPort = 13000;
private static int PortUnknown = -1;
private static string IPAddrUnknown = "";
#region IRegionModule Members
public void Initialise(Scene scene, IConfigSource config)
@ -96,20 +98,22 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//Get sync server info for Client Manager actors
string serverAddr = scene.RegionInfo.RegionName + "_ServerIPAddress";
m_serveraddr = syncConfig.GetString(serverAddr, "127.0.0.1");
m_serveraddr = syncConfig.GetString(serverAddr, IPAddrUnknown);
string serverPort = scene.RegionInfo.RegionName + "_ServerPort";
m_serverport = syncConfig.GetInt(serverPort, DefaultPort);
m_serverport = syncConfig.GetInt(serverPort, PortUnknown);
// Client manager load balancing
m_maxClientsPerManager = syncConfig.GetInt("MaxClientsPerManager", 100);
DefaultPort++;
//Get sync server info for Script Engine actors
string seServerAddr = scene.RegionInfo.RegionName + "_SceneToSESyncServerIP";
m_seSyncServeraddr = syncConfig.GetString(seServerAddr, "127.0.0.1");
m_seSyncServeraddr = syncConfig.GetString(seServerAddr, IPAddrUnknown);
string seServerPort = scene.RegionInfo.RegionName + "_SceneToSESyncServerPort";
m_seSyncServerport = syncConfig.GetInt(seServerPort, DefaultPort);
m_seSyncServerport = syncConfig.GetInt(seServerPort, PortUnknown);
DefaultPort++;
m_symsync = syncConfig.GetBoolean("SymSync", false);
//Get quark information
QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize);
QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize);
@ -138,23 +142,34 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
//m_scene.EventManager.OnNewPresence += new EventManager.OnNewPresenceDelegate(EventManager_OnNewPresence);
m_scene.EventManager.OnRemovePresence += new EventManager.OnRemovePresenceDelegate(EventManager_OnRemovePresence);
m_scene.SceneGraph.OnObjectCreate += new ObjectCreateDelegate(SceneGraph_OnObjectCreate);
m_scene.SceneGraph.OnObjectDuplicate += new ObjectDuplicateDelegate(SceneGraph_OnObjectDuplicate);
//m_scene.SceneGraph.OnObjectRemove += new ObjectDeleteDelegate(SceneGraph_OnObjectRemove);
//m_scene.StatsReporter.OnSendStatsResult += new SimStatsReporter.SendStatResult(StatsReporter_OnSendStatsResult);
m_scene.EventManager.OnOarFileLoaded += new EventManager.OarFileLoaded(EventManager_OnOarFileLoaded);
m_log.Warn("[REGION SYNC SERVER MODULE] Starting RegionSyncServer");
//SYMMETRIC SYNC: do not handle object updates
if (!m_symsync)
{
m_scene.SceneGraph.OnObjectCreate += new ObjectCreateDelegate(SceneGraph_OnObjectCreate);
m_scene.SceneGraph.OnObjectDuplicate += new ObjectDuplicateDelegate(SceneGraph_OnObjectDuplicate);
//m_scene.SceneGraph.OnObjectRemove += new ObjectDeleteDelegate(SceneGraph_OnObjectRemove);
//m_scene.StatsReporter.OnSendStatsResult += new SimStatsReporter.SendStatResult(StatsReporter_OnSendStatsResult);
m_scene.EventManager.OnOarFileLoaded += new EventManager.OarFileLoaded(EventManager_OnOarFileLoaded);
}
//end of SYMMETRIC SYNC
// Start the server and listen for RegionSyncClients
m_server = new RegionSyncServer(m_scene, m_serveraddr, m_serverport, m_maxClientsPerManager);
m_server.Start();
m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed);
m_statsTimer.Start();
if (!m_serveraddr.Equals(IPAddrUnknown) && m_serverport != PortUnknown)
{
m_log.Warn("[REGION SYNC SERVER MODULE] Starting RegionSyncServer");
m_server = new RegionSyncServer(m_scene, m_serveraddr, m_serverport, m_maxClientsPerManager);
m_server.Start();
m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed);
m_statsTimer.Start();
}
m_log.Warn("[REGION SYNC SERVER MODULE] Starting SceneToScriptEngineSyncServer");
//Start the sync server for script engines
m_sceneToSESyncServer = new SceneToScriptEngineSyncServer(m_scene, m_seSyncServeraddr, m_seSyncServerport);
m_sceneToSESyncServer.Start();
if (!m_seSyncServeraddr.Equals(IPAddrUnknown) && m_seSyncServerport != PortUnknown)
{
m_log.Warn("[REGION SYNC SERVER MODULE] Starting SceneToScriptEngineSyncServer");
//Start the sync server for script engines
m_sceneToSESyncServer = new SceneToScriptEngineSyncServer(m_scene, m_seSyncServeraddr, m_seSyncServerport);
m_sceneToSESyncServer.Start();
}
//m_log.Warn("[REGION SYNC SERVER MODULE] Post-Initialised");
}
@ -259,25 +274,23 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
// Sending the message when it's first queued would yield lower latency but much higher load on the simulator
// as parts may be updated many many times very quickly. Need to implement a higher resolution send in heartbeat
foreach (SceneObjectGroup sog in primUpdates)
//SYMMETRIC SYNC: do not handle object updates
if (!m_symsync)
{
if (!sog.IsDeleted)
foreach (SceneObjectGroup sog in primUpdates)
{
/*
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
m_log.Debug("[REGION SYNC SERVER MODULE]: to update object " + sog.UUID + ", localID: "+sog.LocalId
+ ", with color " + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.A
+ "," + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.B + "," + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.G
+ "," + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.R);
m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.UpdatedObject, sogxml));
* */
//KittyL: modified to broadcast to different types of actors
m_server.BroadcastToCM(RegionSyncMessage.MsgType.UpdatedObject, sog);
m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.UpdatedObject, sog);
if (!sog.IsDeleted)
{
//KittyL: modified to broadcast to different types of actors
if (m_server != null)
m_server.BroadcastToCM(RegionSyncMessage.MsgType.UpdatedObject, sog);
if (m_sceneToSESyncServer != null)
m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.UpdatedObject, sog);
}
}
}
//end of SYMMETRIC SYNC
foreach (ScenePresence presence in presenceUpdates)
{
try
@ -363,7 +376,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
data["localID"] = OSD.FromUInteger(localID);
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
//m_server.BroadcastToCM(rsm);
m_server.Broadcast(rsm);
if(m_server!=null)
m_server.Broadcast(rsm);
//KittyL: Second, tell script engine to remove the object, identified by UUID
//UUID objID = m_scene.GetSceneObjectPart(localID).ParentGroup.UUID;
@ -378,7 +392,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check
//if the object part is already removed is the scene (part==null)
m_log.Debug("Inform script engine about the deleted object");
m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup);
if(m_sceneToSESyncServer!=null)
m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup);
}
}
@ -403,9 +418,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void SendLoadWorldMap(ITerrainChannel heightMap)
{
RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString());
m_server.Broadcast(msg);
if(m_server!=null)
m_server.Broadcast(msg);
//KittyL: added for SE
m_sceneToSESyncServer.SendToAllConnectedSE(msg);
if(m_sceneToSESyncServer!=null)
m_sceneToSESyncServer.SendToAllConnectedSE(msg);
}
#region cruft
@ -469,6 +486,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private int m_seSyncServerport;
private SceneToScriptEngineSyncServer m_sceneToSESyncServer = null;
//a boolean variable to indicate in symmetric sync is configured
private bool m_symsync = false;
public bool IsSymSync
{
get { return IsSymSync; }
}
//quark related information
//private int QuarkInfo.SizeX;
//private int QuarkInfo.SizeY;

View File

@ -302,7 +302,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
#endregion //IRegionSyncModule
#region ICommandableModule Members
private readonly Commander m_commander = new Commander("sync");
private readonly Commander m_commander = new Commander("ssync");
public ICommander CommandInterface
{
get { return m_commander; }
@ -340,7 +340,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
/// <param name="args">Commandline arguments</param>
private void EventManager_OnPluginConsole(string[] args)
{
if (args[0] == "sync")
if (args[0] == "ssync")
{
if (args.Length == 1)
{
@ -366,6 +366,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
// Synchronization related functions, NOT exposed through IRegionSyncModule interface
/////////////////////////////////////////////////////////////////////////////////////////
private static int PortUnknown = -1;
private static string IPAddrUnknown = "";
private ILog m_log;
//private bool m_active = true;
@ -482,8 +485,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private void StartLocalSyncListener()
{
RegionSyncListenerInfo localSyncListenerInfo = GetLocalSyncListenerInfo();
m_localSyncListener = new RegionSyncListener(localSyncListenerInfo, this);
m_localSyncListener.Start();
if (localSyncListenerInfo!=null)
{
m_log.Warn(LogHeader + " Starting SyncListener");
m_localSyncListener = new RegionSyncListener(localSyncListenerInfo, this);
m_localSyncListener.Start();
}
//STATS TIMER: TO BE IMPLEMENTED
//m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed);
@ -494,11 +502,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//For now, we use configuration to access the information. Might be replaced by some Grid Service later on.
private RegionSyncListenerInfo GetLocalSyncListenerInfo()
{
string addr = m_sysConfig.GetString("SyncListenerIPAddress", "127.0.0.1");
int port = m_sysConfig.GetInt("SyncListenerPort", 13000);
RegionSyncListenerInfo info = new RegionSyncListenerInfo(addr, port);
string addr = m_sysConfig.GetString("SyncListenerIPAddress", IPAddrUnknown);
int port = m_sysConfig.GetInt("SyncListenerPort", PortUnknown);
return info;
m_log.Warn(LogHeader + ", listener addr: " + addr + ", port: " + port);
if (!addr.Equals(IPAddrUnknown) && port != PortUnknown)
{
RegionSyncListenerInfo info = new RegionSyncListenerInfo(addr, port);
return info;
}
return null;
}
//Get the information for remote [IP:Port] to connect to for synchronization purpose.
@ -510,13 +525,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
//For now, we assume there is only one remote listener to connect to. Later on,
//we may need to modify the code to read in multiple listeners.
string addr = m_sysConfig.GetString("SyncListenerIPAddress", "127.0.0.1");
int port = m_sysConfig.GetInt("SyncListenerPort", 13000);
RegionSyncListenerInfo info = new RegionSyncListenerInfo(addr, port);
m_remoteSyncListeners = new HashSet<RegionSyncListenerInfo>();
m_remoteSyncListeners.Add(info);
string addr = m_sysConfig.GetString("SyncListenerIPAddress", IPAddrUnknown);
int port = m_sysConfig.GetInt("SyncListenerPort", PortUnknown);
if (!addr.Equals(IPAddrUnknown) && port != PortUnknown)
{
RegionSyncListenerInfo info = new RegionSyncListenerInfo(addr, port);
m_remoteSyncListeners = new HashSet<RegionSyncListenerInfo>();
m_remoteSyncListeners.Add(info);
}
}
//Start SyncListener if a listener is supposed to run on this actor; Otherwise, initiate connections to remote listeners.

View File

@ -38,6 +38,9 @@ namespace OpenSim.Region.Framework.Interfaces
bool Active { get; }
bool Synced { get; }
bool IsSymSync { get; } //If SymSync is set to true in the config file, then Symmetric Sync is running and object updates should be handled through RegionSyncModule
void QueuePartForUpdate(SceneObjectPart part);
void QueuePresenceForTerseUpdate(ScenePresence presence);
void SendUpdates();