From: Christopher Yeoh <yeohc@au1.ibm.com>

Adding Oarfileloaded and EmptyScriptCompileQueue event support which
allows (with a module) for programmatic notification of when a region
objects and scripts are up and running after a server start or
load-oar.
0.6.3-post-fixes
Dr Scofield 2009-01-28 09:22:12 +00:00
parent fe18adbc11
commit a3ac702941
3 changed files with 111 additions and 38 deletions

View File

@ -53,6 +53,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
private Scene m_scene; private Scene m_scene;
private Stream m_loadStream; private Stream m_loadStream;
private string m_errorMessage;
/// <summary> /// <summary>
/// Used to cache lookups for valid uuids. /// Used to cache lookups for valid uuids.
@ -63,6 +64,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
{ {
m_scene = scene; m_scene = scene;
m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress); m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress);
m_errorMessage = String.Empty;
} }
public ArchiveReadRequest(Scene scene, Stream loadStream) public ArchiveReadRequest(Scene scene, Stream loadStream)
@ -82,62 +84,76 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
private void DearchiveRegion0DotStar() private void DearchiveRegion0DotStar()
{ {
TarArchiveReader archive = new TarArchiveReader(m_loadStream);
//AssetsDearchiver dearchiver = new AssetsDearchiver(m_scene.AssetCache);
List<string> serialisedSceneObjects = new List<string>();
string filePath = "ERROR";
int successfulAssetRestores = 0; int successfulAssetRestores = 0;
int failedAssetRestores = 0; int failedAssetRestores = 0;
List<string> serialisedSceneObjects = new List<string>();
byte[] data; try
TarArchiveReader.TarEntryType entryType;
while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
{ {
//m_log.DebugFormat( TarArchiveReader archive = new TarArchiveReader(m_loadStream);
// "[ARCHIVER]: Successfully read {0} ({1} bytes)}", filePath, data.Length);
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) //AssetsDearchiver dearchiver = new AssetsDearchiver(m_scene.AssetCache);
string filePath = "ERROR";
byte[] data;
TarArchiveReader.TarEntryType entryType;
while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
{ {
m_log.WarnFormat("[ARCHIVER]: Ignoring directory entry {0}", //m_log.DebugFormat(
filePath); // "[ARCHIVER]: Successfully read {0} ({1} bytes)}", filePath, data.Length);
} if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) {
{ m_log.WarnFormat("[ARCHIVER]: Ignoring directory entry {0}",
serialisedSceneObjects.Add(m_asciiEncoding.GetString(data)); filePath);
} }
else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
{
serialisedSceneObjects.Add(m_asciiEncoding.GetString(data));
}
// else if (filePath.Equals(ArchiveConstants.ASSETS_METADATA_PATH)) // else if (filePath.Equals(ArchiveConstants.ASSETS_METADATA_PATH))
// { // {
// string xml = m_asciiEncoding.GetString(data); // string xml = m_asciiEncoding.GetString(data);
// dearchiver.AddAssetMetadata(xml); // dearchiver.AddAssetMetadata(xml);
// } // }
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
{ {
if (LoadAsset(filePath, data)) if (LoadAsset(filePath, data))
successfulAssetRestores++; successfulAssetRestores++;
else else
failedAssetRestores++; failedAssetRestores++;
} }
else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
{ {
LoadTerrain(filePath, data); LoadTerrain(filePath, data);
} }
else if (filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) else if (filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
{ {
LoadRegionSettings(filePath, data); LoadRegionSettings(filePath, data);
}
} }
//m_log.Debug("[ARCHIVER]: Reached end of archive");
archive.Close();
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ARCHIVER]: Error loading oar file. Exception was: {0}", e);
m_errorMessage += e.ToString();
m_scene.EventManager.TriggerOarFileLoaded(m_errorMessage);
return;
} }
//m_log.Debug("[ARCHIVER]: Reached end of archive");
archive.Close();
m_log.InfoFormat("[ARCHIVER]: Restored {0} assets", successfulAssetRestores); m_log.InfoFormat("[ARCHIVER]: Restored {0} assets", successfulAssetRestores);
if (failedAssetRestores > 0) if (failedAssetRestores > 0)
{
m_log.ErrorFormat("[ARCHIVER]: Failed to load {0} assets", failedAssetRestores); m_log.ErrorFormat("[ARCHIVER]: Failed to load {0} assets", failedAssetRestores);
m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores);
}
m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); m_log.Info("[ARCHIVER]: Clearing all existing scene objects");
m_scene.DeleteAllSceneObjects(); m_scene.DeleteAllSceneObjects();
@ -217,6 +233,8 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
{ {
sceneObject.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 0); sceneObject.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 0);
} }
m_scene.EventManager.TriggerOarFileLoaded(m_errorMessage);
} }
/// <summary> /// <summary>

View File

@ -266,6 +266,21 @@ namespace OpenSim.Region.Environment.Scenes
public delegate float SunLindenHour(); public delegate float SunLindenHour();
public event SunLindenHour OnGetSunLindenHour; public event SunLindenHour OnGetSunLindenHour;
/// <summary>
/// Called when oar file has finished loading, although
/// the scripts may not have started yet
/// Message is non empty string if there were problems loading the oar file
/// </summary>
public delegate void OarFileLoaded(string message);
public event OarFileLoaded OnOarFileLoaded;
/// <summary>
/// Called when the script compile queue becomes empty
/// Returns the number of scripts which failed to start
/// </summary>
public delegate void EmptyScriptCompileQueue(int numScriptsFailed, string message);
public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue;
public class MoneyTransferArgs : EventArgs public class MoneyTransferArgs : EventArgs
{ {
public UUID sender; public UUID sender;
@ -399,6 +414,8 @@ namespace OpenSim.Region.Environment.Scenes
private SunLindenHour handlerSunGetLindenHour = null; private SunLindenHour handlerSunGetLindenHour = null;
private OnSetRootAgentSceneDelegate handlerSetRootAgentScene = null; private OnSetRootAgentSceneDelegate handlerSetRootAgentScene = null;
private OarFileLoaded handlerOarFileLoaded = null;
private EmptyScriptCompileQueue handlerEmptyScriptCompileQueue = null;
public void TriggerGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) public void TriggerGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
{ {
@ -902,6 +919,20 @@ namespace OpenSim.Region.Environment.Scenes
return 6; return 6;
} }
public void TriggerOarFileLoaded(string message)
{
handlerOarFileLoaded = OnOarFileLoaded;
if (handlerOarFileLoaded != null)
handlerOarFileLoaded(message);
}
public void TriggerEmptyScriptCompileQueue(int numScriptsFailed, string message)
{
handlerEmptyScriptCompileQueue = OnEmptyScriptCompileQueue;
if (handlerEmptyScriptCompileQueue != null)
handlerEmptyScriptCompileQueue(numScriptsFailed, message);
}
public void TriggerScriptCollidingStart(uint localId, ColliderArgs colliders) public void TriggerScriptCollidingStart(uint localId, ColliderArgs colliders)
{ {
handlerCollidingStart = OnScriptColliderStart; handlerCollidingStart = OnScriptColliderStart;

View File

@ -71,6 +71,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
private ThreadPriority m_Prio; private ThreadPriority m_Prio;
private bool m_Enabled = false; private bool m_Enabled = false;
private bool m_InitialStartup = true; private bool m_InitialStartup = true;
private int m_ScriptFailCount; // Number of script fails since compile queue was last empty
private string m_ScriptErrorMessage;
// disable warning: need to keep a reference to XEngine.EventManager // disable warning: need to keep a reference to XEngine.EventManager
// alive to avoid it being garbage collected // alive to avoid it being garbage collected
@ -149,6 +151,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public void Initialise(Scene scene, IConfigSource configSource) public void Initialise(Scene scene, IConfigSource configSource)
{ {
m_ScriptConfig = configSource.Configs["XEngine"]; m_ScriptConfig = configSource.Configs["XEngine"];
m_ScriptFailCount = 0;
m_ScriptErrorMessage = String.Empty;
if (m_ScriptConfig == null) if (m_ScriptConfig == null)
{ {
@ -417,6 +421,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
{ {
m_InitialStartup = false; m_InitialStartup = false;
System.Threading.Thread.Sleep(15000); System.Threading.Thread.Sleep(15000);
lock (m_CompileQueue)
{
if (m_CompileQueue.Count==0)
// No scripts on region, so won't get triggered later
// by the queue becoming empty so we trigger it here
m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty);
}
} }
Object o; Object o;
@ -443,6 +454,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
else else
{ {
m_CurrentCompile = null; m_CurrentCompile = null;
m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
m_ScriptErrorMessage);
m_ScriptFailCount = 0;
} }
} }
return null; return null;
@ -468,12 +482,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (part == null) if (part == null)
{ {
Log.Error("[Script] SceneObjectPart unavailable. Script NOT started."); Log.Error("[Script] SceneObjectPart unavailable. Script NOT started.");
m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n";
m_ScriptFailCount++;
return false; return false;
} }
TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID);
if (item == null) if (item == null)
{
m_ScriptErrorMessage += "Can't find script inventory item.\n";
m_ScriptFailCount++;
return false; return false;
}
UUID assetID = item.AssetID; UUID assetID = item.AssetID;
@ -499,6 +519,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
try try
{ {
// DISPLAY ERROR INWORLD // DISPLAY ERROR INWORLD
m_ScriptErrorMessage += "Failed to compile: " + e.Message.ToString();
m_ScriptFailCount++;
string text = "Error compiling script:\n" + e.Message.ToString(); string text = "Error compiling script:\n" + e.Message.ToString();
if (text.Length > 1000) if (text.Length > 1000)
text = text.Substring(0, 1000); text = text.Substring(0, 1000);
@ -567,6 +589,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
m_ScriptErrorMessage += "Exception creating app domain:\n";
m_ScriptFailCount++;
return false; return false;
} }
} }