From 3fe6b2280d0b335ef8d9f2b0dc3406a47e6c0b53 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Mon, 21 Jan 2008 23:04:42 +0000
Subject: * Shutting down child agents properly in neighbor regions.
---
.../Communications/Local/LocalBackEndServices.cs | 25 ++++++---
.../Region/Communications/OGS1/OGS1GridServices.cs | 64 +++++++++++++++++++++-
.../Communications/OGS1/OGS1InterSimComms.cs | 28 ++++++++++
OpenSim/Region/Environment/Scenes/Scene.cs | 6 +-
.../Scenes/SceneCommunicationService.cs | 64 ++++++++++++++++++----
5 files changed, 164 insertions(+), 23 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs
index 5b16e5a..25452c1 100644
--- a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs
+++ b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs
@@ -203,7 +203,14 @@ namespace OpenSim.Region.Communications.Local
}
return mapBlocks;
}
-
+ public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
+ {
+ if (m_regionListeners.ContainsKey(regionHandle))
+ {
+ return m_regionListeners[regionHandle].TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
+ }
+ return false;
+ }
public virtual bool RegionUp(SearializableRegionInfo sregion, ulong regionhandle)
{
@@ -267,6 +274,14 @@ namespace OpenSim.Region.Communications.Local
return false;
}
+ public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
+ {
+ if (m_regionListeners.ContainsKey(regionHandle))
+ {
+ return m_regionListeners[regionHandle].TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
+ }
+ return false;
+ }
///
///
///
@@ -328,13 +343,7 @@ namespace OpenSim.Region.Communications.Local
return false;
}
- public void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
- {
- if (m_regionListeners.ContainsKey(regionHandle))
- {
- m_regionListeners[regionHandle].TriggerCloseAgentConnection(regionHandle, agentID);
- }
- }
+
public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId)
{
diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
index 2ca9022..683fbfb 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
@@ -491,7 +491,8 @@ namespace OpenSim.Region.Communications.OGS1
InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing;
InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp;
InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate;
- //InterRegionSingleton.Instance.OnRegionUp += RegionUp;
+ InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection;
+
}
#region Methods called by regions in this instance
@@ -959,8 +960,53 @@ namespace OpenSim.Region.Communications.OGS1
}
}
- public void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
+ public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
{
+ RegionInfo regInfo = null;
+ try
+ {
+ if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID))
+ {
+ return true;
+ }
+
+ regInfo = RequestNeighbourInfo(regionHandle);
+ if (regInfo != null)
+ {
+ bool retValue = false;
+ OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
+ typeof(OGS1InterRegionRemoting),
+ "tcp://" + regInfo.RemotingAddress +
+ ":" + regInfo.RemotingPort +
+ "/InterRegions");
+ if (remObject != null)
+ {
+ retValue =
+ remObject.TellRegionToCloseChildConnection(regionHandle, agentID.UUID);
+ }
+ else
+ {
+ Console.WriteLine("remoting object not found");
+ }
+ remObject = null;
+
+ return true;
+ }
+ //TODO need to see if we know about where this region is and use .net remoting
+ // to inform it.
+ return false;
+ }
+ catch (RemotingException e)
+ {
+ MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName +
+ " " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
+ //MainLog.Instance.Debug(e.ToString());
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
}
public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId)
@@ -1086,6 +1132,20 @@ namespace OpenSim.Region.Communications.OGS1
}
}
+ public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
+ {
+ try
+ {
+ return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
+ }
+ catch (RemotingException)
+ {
+ MainLog.Instance.Verbose("INTERREGION", "Remoting Error: Unable to connect to neighbour to tell it to close a child connection");
+ return false;
+ }
+
+ }
+
#endregion
#endregion
diff --git a/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs b/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs
index a0da07e..b39e0b7 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs
@@ -45,6 +45,8 @@ namespace OpenSim.Region.Communications.OGS1
public delegate bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate childUpdate);
+ public delegate bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID);
+
public sealed class InterRegionSingleton
{
private static readonly InterRegionSingleton instance = new InterRegionSingleton();
@@ -55,6 +57,8 @@ namespace OpenSim.Region.Communications.OGS1
public event PrimGroupArrival OnPrimGroupArrival;
public event RegionUp OnRegionUp;
public event ChildAgentUpdate OnChildAgentUpdate;
+ public event TellRegionToCloseChildConnection OnTellRegionToCloseChildConnection;
+
static InterRegionSingleton()
@@ -123,6 +127,16 @@ namespace OpenSim.Region.Communications.OGS1
}
return false;
}
+
+ public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
+ {
+ if (OnTellRegionToCloseChildConnection != null)
+ {
+
+ return OnTellRegionToCloseChildConnection(regionHandle, agentID);
+ }
+ return false;
+ }
}
public class OGS1InterRegionRemoting : MarshalByRefObject
@@ -171,6 +185,7 @@ namespace OpenSim.Region.Communications.OGS1
}
}
+
public bool ExpectAvatarCrossing(ulong regionHandle, Guid agentID, sLLVector3 position, bool isFlying)
{
try
@@ -215,5 +230,18 @@ namespace OpenSim.Region.Communications.OGS1
return false;
}
}
+ public bool TellRegionToCloseChildConnection(ulong regionHandle, Guid agentID)
+ {
+ try
+ {
+ return InterRegionSingleton.Instance.TellRegionToCloseChildConnection(regionHandle, new LLUUID(agentID));
+
+ }
+ catch (RemotingException)
+ {
+ OpenSim.Framework.Console.MainLog.Instance.Verbose("INTERREGION", "Remoting Error: Unable to connect to remote region: " + regionHandle.ToString());
+ return false;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 2f961c1..7175d83 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -1288,6 +1288,7 @@ namespace OpenSim.Region.Environment.Scenes
CommsManager.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle,
avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y,
avatar.AbsolutePosition.Z);
+ m_sceneGridService.SendCloseChildAgentConnections(avatar);
}
}
catch (NullReferenceException)
@@ -1389,6 +1390,7 @@ namespace OpenSim.Region.Environment.Scenes
m_sceneGridService.OnCloseAgentConnection += CloseConnection;
m_sceneGridService.OnRegionUp += OtherRegionUp;
m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
+
m_sceneGridService.KillObject = SendKillObject;
@@ -1509,7 +1511,7 @@ namespace OpenSim.Region.Environment.Scenes
///
///
///
- public void CloseConnection(ulong regionHandle, LLUUID agentID)
+ public bool CloseConnection(ulong regionHandle, LLUUID agentID)
{
if (regionHandle == m_regionHandle)
{
@@ -1527,8 +1529,10 @@ namespace OpenSim.Region.Environment.Scenes
// Tell a single agent to disconnect from the region.
libsecondlife.Packets.DisableSimulatorPacket disable = (libsecondlife.Packets.DisableSimulatorPacket) PacketPool.Instance.GetPacket(libsecondlife.Packets.PacketType.DisableSimulator);
presence.ControllingClient.OutPacket(disable, ThrottleOutPacketType.Task);
+ presence.ControllingClient.Close(true);
}
}
+ return true;
}
///
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
index 666edb1..a9c2c2f 100644
--- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
@@ -51,6 +51,7 @@ namespace OpenSim.Region.Environment.Scenes
public event PrimCrossing OnPrimCrossingIntoRegion;
public event RegionUp OnRegionUp;
public event ChildAgentUpdate OnChildAgentUpdate;
+
public KillObjectDelegate KillObject;
@@ -86,6 +87,7 @@ namespace OpenSim.Region.Environment.Scenes
regionCommsHost.OnCloseAgentConnection += CloseConnection;
regionCommsHost.OnRegionUp += newRegionUp;
regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate;
+
}
else
{
@@ -160,12 +162,15 @@ namespace OpenSim.Region.Environment.Scenes
}
}
- protected void CloseConnection(ulong regionHandle, LLUUID agentID)
+ protected bool CloseConnection(ulong regionHandle, LLUUID agentID)
{
+ MainLog.Instance.Verbose("INTERREGION", "Incoming Agent Close Request for agent: " + agentID.ToString());
+
if (OnCloseAgentConnection != null)
{
- OnCloseAgentConnection(regionHandle, agentID);
+ return OnCloseAgentConnection(regionHandle, agentID);
}
+ return false;
}
#endregion
@@ -366,6 +371,50 @@ namespace OpenSim.Region.Environment.Scenes
d);
}
+ public delegate void SendCloseChildAgentDelegate( ScenePresence presence);
+
+ ///
+ /// This informs all neighboring regions about the settings of it's child agent.
+ /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
+ ///
+ /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
+ ///
+ ///
+ private void SendCloseChildAgentAsync(ScenePresence presence)
+ {
+
+ foreach (ulong regionHandle in presence.KnownChildRegions)
+ {
+ bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, presence.ControllingClient.AgentId);
+
+ if (regionAccepted)
+ {
+ MainLog.Instance.Notice("INTERGRID", "Completed sending agent Close agent Request to neighbor");
+ presence.RemoveNeighbourRegion(regionHandle);
+ }
+ else
+ {
+ MainLog.Instance.Notice("INTERGRID", "Failed sending agent Close agent Request to neighbor");
+
+ }
+
+ }
+ }
+
+ private void SendCloseChildAgentCompleted(IAsyncResult iar)
+ {
+ SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState;
+ icon.EndInvoke(iar);
+ }
+
+ public void SendCloseChildAgentConnections(ScenePresence presence)
+ {
+ // This assumes that we know what our neighbors are.
+ SendCloseChildAgentDelegate d = SendCloseChildAgentAsync;
+ d.BeginInvoke(presence,
+ SendCloseChildAgentCompleted,
+ d);
+ }
///
/// Helper function to request neighbors from grid-comms
@@ -454,7 +503,7 @@ namespace OpenSim.Region.Environment.Scenes
uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
if (Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3)
{
- CloseChildAgentConnections(avatar);
+ SendCloseChildAgentConnections(avatar);
}
}
else
@@ -481,15 +530,6 @@ namespace OpenSim.Region.Environment.Scenes
return m_commsProvider.InterRegion.ExpectPrimCrossing(regionhandle, primID, position, isPhysical);
}
- public void CloseChildAgentConnections(ScenePresence presence)
- {
- foreach (ulong regionHandle in presence.KnownChildRegions)
- {
- m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle,
- presence.ControllingClient.AgentId);
- presence.RemoveNeighbourRegion(regionHandle);
- }
- }
public Dictionary GetGridSettings()
{
--
cgit v1.1