Possible fix for: Remoting exceptions with adjacent non-running sims.

Bugs 449, 454, 408, 244, 197
implemented InformClientOfNeighbours as an asynchroneous process, handling timeouts without blocking the main thread.

Improved logging of errors, removed catch all in try catch
afrisby
Tleiades Hax 2007-10-18 15:10:43 +00:00
parent 404e2b6cf2
commit 05df857132
14 changed files with 148 additions and 82 deletions

View File

@ -27,6 +27,9 @@
*/
using System.Collections.Generic;
using System.Net;
using libsecondlife;
using OpenSim.Framework.Types;
namespace OpenSim.Framework.Communications
@ -34,7 +37,7 @@ namespace OpenSim.Framework.Communications
public interface IGridServices
{
RegionCommsListener RegisterRegion(RegionInfo regionInfos);
List<RegionInfo> RequestNeighbours(RegionInfo regionInfo);
List<SimpleRegionInfo> RequestNeighbours(uint x, uint y);
RegionInfo RequestNeighbourInfo(ulong regionHandle);
List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY);
}

View File

@ -40,20 +40,51 @@ using OpenSim.Framework.Configuration;
namespace OpenSim.Framework.Types
{
public class RegionInfo
public class SimpleRegionInfo
{
public LLUUID SimUUID = new LLUUID();
public string RegionName = "";
public SimpleRegionInfo()
{
}
private IPEndPoint m_internalEndPoint;
public IPEndPoint InternalEndPoint
public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
{
m_regionLocX = regionLocX;
m_regionLocY = regionLocY;
m_internalEndPoint = internalEndPoint;
m_externalHostName = externalUri;
}
public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, int port)
{
m_regionLocX = regionLocX;
m_regionLocY = regionLocY;
m_externalHostName = externalUri;
m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
}
public LLUUID RegionID = new LLUUID();
private uint m_remotingPort;
public uint RemotingPort
{
get
{
return m_internalEndPoint;
return m_remotingPort;
}
set
{
m_remotingPort = value;
}
}
public string RemotingAddress;
public IPEndPoint ExternalEndPoint
{
get
@ -86,9 +117,14 @@ namespace OpenSim.Framework.Types
return new IPEndPoint(ia, m_internalEndPoint.Port);
}
set
{
m_externalHostName = value.ToString();
}
}
private string m_externalHostName;
protected string m_externalHostName;
public string ExternalHostName
{
get
@ -97,7 +133,16 @@ namespace OpenSim.Framework.Types
}
}
private uint? m_regionLocX;
protected IPEndPoint m_internalEndPoint;
public IPEndPoint InternalEndPoint
{
get
{
return m_internalEndPoint;
}
}
protected uint? m_regionLocX;
public uint RegionLocX
{
get
@ -106,7 +151,7 @@ namespace OpenSim.Framework.Types
}
}
private uint? m_regionLocY;
protected uint? m_regionLocY;
public uint RegionLocY
{
get
@ -115,33 +160,18 @@ namespace OpenSim.Framework.Types
}
}
private ulong? m_regionHandle;
public ulong RegionHandle
{
get
{
if (!m_regionHandle.HasValue)
{
m_regionHandle = Util.UIntsToLong((RegionLocX * 256), (RegionLocY * 256));
}
return m_regionHandle.Value;
return Util.UIntsToLong((RegionLocX * 256), (RegionLocY * 256));
}
}
}
private uint m_remotingPort;
public uint RemotingPort
{
get
{
return m_remotingPort;
}
set
{
m_remotingPort = value;
}
}
public string RemotingAddress;
public class RegionInfo : SimpleRegionInfo
{
public string RegionName = "";
public string DataStore = "";
public bool isSandbox = false;
@ -161,15 +191,11 @@ namespace OpenSim.Framework.Types
configMember.performConfigurationRetrieve();
}
public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) :
base(regionLocX, regionLocY, internalEndPoint, externalUri)
{
estateSettings = new EstateSettings();
m_regionLocX = regionLocX;
m_regionLocY = regionLocY;
m_internalEndPoint = internalEndPoint;
m_externalHostName = externalUri;
}
public void LoadFromNiniSource(IConfigSource source)
@ -180,7 +206,7 @@ namespace OpenSim.Framework.Types
public void LoadFromNiniSource(IConfigSource source, string sectionName)
{
string errorMessage = "";
this.SimUUID = new LLUUID(source.Configs[sectionName].GetString("sim_UUID", LLUUID.Random().ToStringHyphenated()));
this.RegionID = new LLUUID(source.Configs[sectionName].GetString("Region_ID", LLUUID.Random().ToStringHyphenated()));
this.RegionName = source.Configs[sectionName].GetString("sim_name", "OpenSim Test");
this.m_regionLocX = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_x", "1000"));
this.m_regionLocY = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_y", "1000"));
@ -220,7 +246,7 @@ namespace OpenSim.Framework.Types
public void loadConfigurationOptions()
{
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "UUID of Simulator (Default is recommended, random UUID)", LLUUID.Random().ToString(), true);
configMember.addConfigurationOption("Region_ID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "UUID of Simulator (Default is recommended, random UUID)", LLUUID.Random().ToString(), true);
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Simulator Name", "OpenSim Test", false);
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "Grid Location (X Axis)", "1000", false);
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "Grid Location (Y Axis)", "1000", false);
@ -238,7 +264,7 @@ namespace OpenSim.Framework.Types
switch (configuration_key)
{
case "sim_UUID":
this.SimUUID = (LLUUID)configuration_result;
this.RegionID = (LLUUID)configuration_result;
break;
case "sim_name":
this.RegionName = (string)configuration_result;

View File

@ -482,6 +482,7 @@ namespace OpenSim.Grid.GridServer
simProfileBlock["sim_port"] = aSim.Value.serverPort.ToString();
simProfileBlock["sim_uri"] = aSim.Value.serverURI.ToString();
simProfileBlock["uuid"] = aSim.Value.UUID.ToStringHyphenated();
simProfileBlock["remoting_port"] = aSim.Value.remotingPort;
simProfileList.Add(simProfileBlock);
}

View File

@ -1168,7 +1168,7 @@ namespace OpenSim.Grid.ScriptEngine.DotNetEngine.Compiler
if (dynamicID == "")
{
IDynamicTextureManager textureManager = this.World.RequestModuleInterface<IDynamicTextureManager>();
LLUUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.SimUUID, this.m_host.UUID, contentType, url, extraParams, timer);
LLUUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, this.m_host.UUID, contentType, url, extraParams, timer);
return createdTexture.ToStringHyphenated();
}
else

View File

@ -519,7 +519,7 @@ namespace OpenSim.Region.ClientStack
{
AssetLandmark lm = new AssetLandmark(lma);
if (lm.RegionID == m_scene.RegionInfo.SimUUID)
if (lm.RegionID == m_scene.RegionInfo.RegionID)
{
TeleportLocalPacket tpLocal = new TeleportLocalPacket();

View File

@ -72,20 +72,20 @@ namespace OpenSim.Region.Communications.Local
/// </summary>
/// <param name="regionInfo"></param>
/// <returns></returns>
public List<RegionInfo> RequestNeighbours(RegionInfo regionInfo)
public List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
{
// Console.WriteLine("Finding Neighbours to " + regionInfo.RegionHandle);
List<RegionInfo> neighbours = new List<RegionInfo>();
List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
foreach (RegionInfo reg in this.m_regions.Values)
foreach (RegionInfo reg in m_regions.Values)
{
// Console.WriteLine("CommsManager- RequestNeighbours() checking region " + reg.RegionLocX + " , "+ reg.RegionLocY);
if (reg.RegionHandle != regionInfo.RegionHandle)
if (reg.RegionLocX != x || reg.RegionLocY != y)
{
//Console.WriteLine("CommsManager- RequestNeighbours() - found a different region in list, checking location");
if ((reg.RegionLocX > (regionInfo.RegionLocX - 2)) && (reg.RegionLocX < (regionInfo.RegionLocX + 2)))
if ((reg.RegionLocX > (x - 2)) && (reg.RegionLocX < (x + 2)))
{
if ((reg.RegionLocY > (regionInfo.RegionLocY - 2)) && (reg.RegionLocY < (regionInfo.RegionLocY + 2)))
if ((reg.RegionLocY > (x - 2)) && (reg.RegionLocY < (x + 2)))
{
neighbours.Add(reg);
}
@ -223,7 +223,7 @@ namespace OpenSim.Region.Communications.Local
regData["status"] = "active";
regData["handle"] = region.ToString();
respData[reg.SimUUID.ToStringHyphenated()] = regData;
respData[reg.RegionID.ToStringHyphenated()] = regData;
}
}
@ -254,3 +254,4 @@ namespace OpenSim.Region.Communications.Local
}
}

View File

@ -127,7 +127,7 @@ namespace OpenSim.Region.Communications.Local
response.SeedCapability = "http://" + reg.ExternalHostName + ":" + this.serversInfo.HttpListenerPort.ToString() + "/CAPS/" + capsPath + "0000/";
// response.SeedCapability = "http://" + reg.ExternalHostName + ":" + this.serversInfo.HttpListenerPort.ToString() + "/CapsSeed/" + capsPath + "0000/";
theUser.currentAgent.currentRegion = reg.SimUUID;
theUser.currentAgent.currentRegion = reg.RegionID;
theUser.currentAgent.currentHandle = reg.RegionHandle;
Login _login = new Login();

View File

@ -30,9 +30,12 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Security.Authentication;
using libsecondlife;
using Nwc.XmlRpc;
using OpenSim.Framework;
@ -78,7 +81,7 @@ namespace OpenSim.Region.Communications.OGS1
// Login / Authentication
GridParams["authkey"] = serversInfo.GridSendKey;
GridParams["UUID"] = regionInfo.SimUUID.ToStringHyphenated();
GridParams["UUID"] = regionInfo.RegionID.ToStringHyphenated();
GridParams["sim_ip"] = regionInfo.ExternalHostName;
GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString();
GridParams["region_locx"] = regionInfo.RegionLocX.ToString();
@ -115,12 +118,12 @@ namespace OpenSim.Region.Communications.OGS1
/// </summary>
/// <param name="regionInfo"></param>
/// <returns></returns>
public List<RegionInfo> RequestNeighbours(RegionInfo regionInfo)
public List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
{
Hashtable respData = MapBlockQuery((int)regionInfo.RegionLocX - 1, (int)regionInfo.RegionLocY - 1, (int)regionInfo.RegionLocX + 1, (int)regionInfo.RegionLocY + 1);
Hashtable respData = MapBlockQuery((int)x - 1, (int)y - 1, (int)x + 1, (int)y + 1);
List<RegionInfo> neighbours = new List<RegionInfo>();
List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
foreach (ArrayList neighboursList in respData.Values)
{
@ -128,27 +131,20 @@ namespace OpenSim.Region.Communications.OGS1
{
uint regX = Convert.ToUInt32(neighbourData["x"]);
uint regY = Convert.ToUInt32(neighbourData["y"]);
if ((regionInfo.RegionLocX != regX) || (regionInfo.RegionLocY != regY))
if ((x != regX) || (y != regY))
{
string simIp = (string)neighbourData["sim_ip"];
uint port = Convert.ToUInt32(neighbourData["sim_port"]);
int port = Convert.ToInt32(neighbourData["sim_port"]);
string externalUri = (string)neighbourData["sim_uri"];
string externalIpStr = OpenSim.Framework.Utilities.Util.GetHostFromDNS(simIp).ToString();
IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(externalIpStr), (int)port);
string neighbourExternalUri = externalUri;
RegionInfo neighbour = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalIpStr);
SimpleRegionInfo sri = new SimpleRegionInfo(regX, regY, simIp, port);
sri.RemotingPort = Convert.ToUInt32(neighbourData["remoting_port"]);
sri.RegionID = new LLUUID((string)neighbourData["uuid"]);
//OGS1
//neighbour.RegionHandle = (ulong)n["regionhandle"]; is now calculated locally
neighbour.RegionName = (string)neighbourData["name"];
//OGS1+
neighbour.SimUUID = new LLUUID((string)neighbourData["uuid"]);
neighbours.Add(neighbour);
neighbours.Add(sri);
}
}
}
@ -199,7 +195,7 @@ namespace OpenSim.Region.Communications.OGS1
regionInfo.RemotingPort = Convert.ToUInt32((string)responseData["remoting_port"]);
regionInfo.RemotingAddress = internalIpStr;
regionInfo.SimUUID = new LLUUID((string)responseData["region_UUID"]);
regionInfo.RegionID = new LLUUID((string)responseData["region_UUID"]);
regionInfo.RegionName = (string)responseData["region_name"];
return regionInfo;
@ -365,6 +361,7 @@ namespace OpenSim.Region.Communications.OGS1
OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
typeof(OGS1InterRegionRemoting),
"tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + "/InterRegions");
if (remObject != null)
{
retValue = remObject.InformRegionOfChildAgent(regionHandle, agentData);
@ -386,10 +383,27 @@ namespace OpenSim.Region.Communications.OGS1
MainLog.Instance.Error("Remoting Error: Unable to connect to remote region.\n" + e.ToString());
return false;
}
catch
catch (SocketException e)
{
MainLog.Instance.Error("Socket Error: Unable to connect to remote region.\n" + e.ToString());
return false;
}
catch (InvalidCredentialException e)
{
MainLog.Instance.Error("Invalid Credentials: Unable to connect to remote region.\n" + e.ToString());
return false;
}
catch (AuthenticationException e)
{
MainLog.Instance.Error("Authentication exception: Unable to connect to remote region.\n" + e.ToString());
return false;
}
catch (Exception e)
{
MainLog.Instance.Error("Unknown exception: Unable to connect to remote region.\n" + e.ToString());
return false;
}
return true;
}
/// <summary>

View File

@ -47,9 +47,9 @@ namespace OpenSim.Region.Environment.Modules
public void Initialise(Scene scene)
{
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.SimUUID))
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
{
RegisteredScenes.Add(scene.RegionInfo.SimUUID, scene);
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
scene.RegisterModuleInterface<IDynamicTextureManager>(this);
}
}

View File

@ -403,7 +403,7 @@ namespace OpenSim.Region.Environment.Scenes
}
storageManager.DataStore.RemoveObject(((SceneObjectGroup) selectedEnt).UUID,
m_regInfo.SimUUID);
m_regInfo.RegionID);
((SceneObjectGroup) selectedEnt).DeleteGroup();
lock (Entities)

View File

@ -26,6 +26,7 @@
*
*/
using System;
using System.Net;
using System.Collections.Generic;
using System.IO;
using System.Threading;
@ -529,7 +530,7 @@ namespace OpenSim.Region.Environment.Scenes
public virtual void LoadPrimsFromStorage()
{
MainLog.Instance.Verbose("Loading objects from datastore");
List<SceneObjectGroup> PrimsFromDB = storageManager.DataStore.LoadObjects(m_regInfo.SimUUID);
List<SceneObjectGroup> PrimsFromDB = storageManager.DataStore.LoadObjects(m_regInfo.RegionID);
foreach (SceneObjectGroup prim in PrimsFromDB)
{
AddEntityFromStorage(prim);
@ -964,7 +965,7 @@ namespace OpenSim.Region.Environment.Scenes
if (Entities.ContainsKey(entID))
{
Entities.Remove(entID);
storageManager.DataStore.RemoveObject(entID, m_regInfo.SimUUID);
storageManager.DataStore.RemoveObject(entID, m_regInfo.RegionID);
return true;
}
return false;
@ -1062,13 +1063,32 @@ namespace OpenSim.Region.Environment.Scenes
}
}
delegate void InformClientOfNeighbourDelegate(IClientAPI remoteClient, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint);
/// <summary>
/// Async compnent for informing client of which neighbours exists
/// </summary>
/// <remarks>
/// This needs to run asynchronesously, as a network timeout may block the thread for a long while
/// </remarks>
/// <param name="remoteClient"></param>
/// <param name="a"></param>
/// <param name="regionHandle"></param>
/// <param name="endPoint"></param>
public void InformClientOfNeighbourAsync(IClientAPI remoteClient, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint)
{
bool regionAccepted = commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, a);
if (regionAccepted)
remoteClient.InformClientOfNeighbour(regionHandle, endPoint);
}
/// <summary>
///
/// </summary>
public void InformClientOfNeighbours(IClientAPI remoteClient)
{
List<RegionInfo> neighbours = commsManager.GridService.RequestNeighbours(m_regInfo);
List<SimpleRegionInfo> neighbours = commsManager.GridService.RequestNeighbours(m_regInfo.RegionLocX, m_regInfo.RegionLocY);
if (neighbours != null)
{
for (int i = 0; i < neighbours.Count; i++)
@ -1078,8 +1098,9 @@ namespace OpenSim.Region.Environment.Scenes
agent.InventoryFolder = LLUUID.Zero;
agent.startpos = new LLVector3(128, 128, 70);
agent.child = true;
commsManager.InterRegion.InformRegionOfChildAgent(neighbours[i].RegionHandle, agent);
remoteClient.InformClientOfNeighbour(neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint);
InformClientOfNeighbourDelegate d = new InformClientOfNeighbourDelegate(InformClientOfNeighbourAsync);
IAsyncResult asyncInform = d.BeginInvoke(remoteClient, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, null, null);
//this.capsHandlers[remoteClient.AgentId].CreateEstablishAgentComms("", System.Net.IPAddress.Parse(neighbours[i].CommsIPListenAddr) + ":" + neighbours[i].CommsIPListenPort);
}
}

View File

@ -197,7 +197,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (m_scene != null)
{
return m_scene.RegionInfo.SimUUID;
return m_scene.RegionInfo.RegionID;
}
return LLUUID.Zero;
}
@ -1173,7 +1173,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (HasChanged)
{
datastore.StoreObject(this, m_scene.RegionInfo.SimUUID);
datastore.StoreObject(this, m_scene.RegionInfo.RegionID);
HasChanged = false;
}
}

View File

@ -770,7 +770,7 @@ namespace OpenSim.Region.Environment.Scenes
protected void CheckForSignificantMovement()
{
if (Helpers.VecDist(AbsolutePosition, posLastSignificantMove) > 2.0)
if (AbsolutePosition.GetDistanceTo(posLastSignificantMove) > 2.0)
{
posLastSignificantMove = AbsolutePosition;
if (OnSignificantClientMovement != null)

View File

@ -1221,7 +1221,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
if (dynamicID == "")
{
IDynamicTextureManager textureManager = this.World.RequestModuleInterface<IDynamicTextureManager>();
LLUUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.SimUUID, this.m_host.UUID, contentType, url, extraParams, timer);
LLUUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, this.m_host.UUID, contentType, url, extraParams, timer);
return createdTexture.ToStringHyphenated();
}
else