From 12c20b2b89f47d5eee20ac85bda880069b1fa7e8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 25 Aug 2020 17:35:54 +0100 Subject: [PATCH] change scene comms and neighbour --- .../Scenes/SceneCommunicationService.cs | 181 ++++++------------ .../Neighbour/NeighbourServicesConnector.cs | 110 ++++------- 2 files changed, 90 insertions(+), 201 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index c89a123e38..cf8b2cd999 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes public class SceneCommunicationService //one instance per region { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static string LogHeader = "[SCENE COMMUNICATION SERVICE]"; + private static readonly string LogHeader = "[SCENE COMM]"; protected RegionInfo m_regionInfo; protected Scene m_scene; @@ -62,126 +62,78 @@ namespace OpenSim.Region.Framework.Scenes m_regionInfo = s.RegionInfo; } - public delegate void InformNeighbourThatRegionUpDelegate(INeighbourService nService, RegionInfo region, ulong regionhandle); - - private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar) - { - InformNeighbourThatRegionUpDelegate icon = (InformNeighbourThatRegionUpDelegate)iar.AsyncState; - icon.EndInvoke(iar); - } - - /// - /// Asynchronous call to information neighbouring regions that this region is up - /// - /// - /// - private void InformNeighboursThatRegionIsUpAsync(INeighbourService neighbourService, RegionInfo region, ulong regionhandle) - { - uint x = 0, y = 0; - Utils.LongToUInts(regionhandle, out x, out y); - - GridRegion neighbour = null; - if (neighbourService != null) - neighbour = neighbourService.HelloNeighbour(regionhandle, region); - else - m_log.ErrorFormat("{0} No neighbour service provided for region {1} to inform neigbhours of status", LogHeader, m_scene.Name); - - if (neighbour != null) - { - m_log.DebugFormat("{0} Region {1} successfully informed neighbour {2} at {3}-{4} that it is up", - LogHeader, m_scene.Name, neighbour.RegionName, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y)); - - m_scene.EventManager.TriggerOnRegionUp(neighbour); - } - else - { - m_log.WarnFormat( - "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.", - m_scene.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y)); - } - } - public void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region) { //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); + if (neighbourService == null) + { + m_log.ErrorFormat("{0} No neighbour service provided for region {1} to inform neigbhours of status", LogHeader, m_scene.Name); + return; + } List neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); - List onlineNeighbours = new List(); + List onlineNeighbours = new List(); foreach (GridRegion n in neighbours) { - OpenSim.Framework.RegionFlags? regionFlags = n.RegionFlags; - - // m_log.DebugFormat( - // "{0}: Region flags for {1} as seen by {2} are {3}", - // LogHeader, n.RegionName, m_scene.Name, regionFlags != null ? regionFlags.ToString() : "not present"); + //m_log.DebugFormat( + // "{0}: Region flags for {1} as seen by {2} are {3}", + // LogHeader, n.RegionName, m_scene.Name, regionFlags != null ? regionFlags.ToString() : "not present"); // Robust services before 2015-01-14 do not return the regionFlags information. In this case, we could // make a separate RegionFlags call but this would involve a network call for each neighbour. - if (regionFlags != null) + if (n.RegionFlags != null) { - if ((regionFlags & OpenSim.Framework.RegionFlags.RegionOnline) != 0) - onlineNeighbours.Add(n); + if ((n.RegionFlags & OpenSim.Framework.RegionFlags.RegionOnline) != 0) + onlineNeighbours.Add(n.RegionHandle); } else { - onlineNeighbours.Add(n); + onlineNeighbours.Add(n.RegionHandle); } } - m_log.DebugFormat( - "{0} Informing {1} neighbours that region {2} is up", - LogHeader, onlineNeighbours.Count, m_scene.Name); - - foreach (GridRegion n in onlineNeighbours) + if(onlineNeighbours.Count > 0) { - InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; - d.BeginInvoke(neighbourService, region, n.RegionHandle, - InformNeighborsThatRegionisUpCompleted, - d); + Util.FireAndForget(o => + { + foreach (ulong regionhandle in onlineNeighbours) + { + Util.RegionHandleToRegionLoc(regionhandle, out uint rx, out uint ry); + GridRegion neighbour = neighbourService.HelloNeighbour(regionhandle, region); + if (neighbour != null) + { + m_log.DebugFormat("{0} Region {1} successfully informed neighbour {2} at {3}-{4} that it is up", + LogHeader, m_scene.Name, neighbour.RegionName, rx, ry); + + m_scene.EventManager.TriggerOnRegionUp(neighbour); + } + else + { + m_log.WarnFormat("{0} Region {1} failed to inform neighbour at {2}-{3} that it is up.", + LogHeader, m_scene.Name, rx, ry); + } + } + }); } } - public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest); - /// /// 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 SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest) - { - //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); - try - { - m_scene.SimulationService.UpdateAgent(dest, cAgentData); - } - catch - { - // Ignore; we did our best - } - } - - private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) - { - SendChildAgentDataUpdateDelegate icon = (SendChildAgentDataUpdateDelegate)iar.AsyncState; - icon.EndInvoke(iar); - } public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence) { - // m_log.DebugFormat( - // "[SCENE COMMUNICATION SERVICE]: Sending child agent position updates for {0} in {1}", - // presence.Name, m_scene.Name); + //m_log.DebugFormat( + // "[SCENE COMMUNICATION SERVICE]: Sending child agent position updates for {0} in {1}", + // presence.Name, m_scene.Name); // This assumes that we know what our neighbors are. try { - uint x = 0, y = 0; List simulatorList = new List(); foreach (ulong regionHandle in presence.KnownRegionHandles) { @@ -190,8 +142,7 @@ namespace OpenSim.Region.Framework.Scenes // we only want to send one update to each simulator; the simulator will // hand it off to the regions where a child agent exists, this does assume // that the region position is cached or performance will degrade - Util.RegionHandleToWorldLoc(regionHandle, out x, out y); - GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); + GridRegion dest = m_scene.GridService.GetRegionByHandle(UUID.Zero, regionHandle); if (dest == null) continue; @@ -200,14 +151,7 @@ namespace OpenSim.Region.Framework.Scenes // we havent seen this simulator before, add it to the list // and send it an update simulatorList.Add(dest.ServerURI); - // Let move this to sync. Mono definitely does not like async networking. m_scene.SimulationService.UpdateAgent(dest, cAgentData); - - // Leaving this here as a reminder that we tried, and it sucks. - //SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; - //d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest, - // SendChildAgentDataUpdateCompleted, - // d); } } } @@ -218,35 +162,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public delegate void SendCloseChildAgentDelegate(UUID agentID, ulong regionHandle); - - /// - /// This Closes child agents on neighboring regions - /// Calls an asynchronous method to do so.. so it doesn't lag the sim. - /// - protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token) - { - // let's do our best, but there's not much we can do if the neighbour doesn't accept. - - //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); - uint x = 0, y = 0; - Util.RegionHandleToWorldLoc(regionHandle, out x, out y); - - GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y); - - if (destination == null) - { - m_log.DebugFormat( - "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} FAIL, region with handle {1} not found", agentID, regionHandle); - return; - } - - m_log.DebugFormat( - "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName); - - m_scene.SimulationService.CloseAgent(destination, agentID, auth_token); - } - /// /// Closes a child agents in a collection of regions. Does so asynchronously /// so that the caller doesn't wait. @@ -261,11 +176,23 @@ namespace OpenSim.Region.Framework.Scenes // use a single thread job for all Util.FireAndForget(o => { - foreach (ulong handle in regionslst) + foreach (ulong regionHandle in regionslst) { - SendCloseChildAgent(agentID, handle, auth_code); + // let's do our best, but there's not much we can do if the neighbour doesn't accept. + GridRegion destination = m_scene.GridService.GetRegionByHandle(m_regionInfo.ScopeID, regionHandle); + if (destination == null) + { + m_log.DebugFormat( + "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} FAIL, region with handle {1} not found", agentID, regionHandle); + return; + } + + m_log.DebugFormat( + "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName); + + m_scene.SimulationService.CloseAgent(destination, agentID, auth_code); } - }, null, "SceneCommunicationService.SendCloseChildAgentConnections"); + }, null, "SCOMM.SendCloseChildAgentConnections"); } public List RequestNamedRegions(string name, int maxNumber) diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs index 9f3b94c78d..3dd0703fae 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs @@ -68,9 +68,7 @@ namespace OpenSim.Services.Connectors public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) { - uint x = 0, y = 0; - Util.RegionHandleToWorldLoc(regionHandle, out x, out y); - GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y); + GridRegion regInfo = m_GridService.GetRegionByHandle(thisRegion.ScopeID, regionHandle); if ((regInfo != null) && // Don't remote-call this instance; that's a startup hickup !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort))) @@ -87,13 +85,30 @@ namespace OpenSim.Services.Connectors public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion) { string uri = region.ServerURI + "region/" + thisRegion.RegionID + "/"; -// m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); - - WebRequest helloNeighbourRequest; + //m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); + byte[] buffer = null; try { - helloNeighbourRequest = WebRequest.Create(uri); + OSDMap args = thisRegion.PackRegionInfoData(); + args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); + buffer = Util.UTF8NoBomEncoding.GetBytes(OSDParser.SerializeJsonString(args)); + } + catch (Exception e) + { + m_log.Warn(string.Format( + "[NEIGHBOUR SERVICES CONNECTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2} ", + thisRegion.RegionName, region.RegionName, e.Message), e); + return false; + } + + if(buffer == null || buffer.Length == 0) + return false; + + HttpWebRequest helloNeighbourRequest; + try + { + helloNeighbourRequest = (HttpWebRequest)WebRequest.Create(uri); } catch (Exception e) { @@ -108,64 +123,23 @@ namespace OpenSim.Services.Connectors helloNeighbourRequest.ContentType = "application/json"; helloNeighbourRequest.Timeout = 10000; - // Fill it in - OSDMap args = null; try { - args = thisRegion.PackRegionInfoData(); - } - catch (Exception e) - { - m_log.Warn(string.Format( - "[NEIGHBOUR SERVICES CONNECTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2} ", - thisRegion.RegionName, region.RegionName, e.Message), e); - - return false; - } - - // Add the regionhandle of the destination region - args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); - - string strBuffer = ""; - byte[] buffer = new byte[1]; - - try - { - strBuffer = OSDParser.SerializeJsonString(args); - buffer = Util.UTF8NoBomEncoding.GetBytes(strBuffer); - } - catch (Exception e) - { - m_log.Warn(string.Format( - "[NEIGHBOUR SERVICES CONNECTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2} ", - thisRegion.RegionName, region.RegionName, e.Message), e); - - return false; - } - - Stream os = null; - try - { // send the Post - helloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send - os = helloNeighbourRequest.GetRequestStream(); - os.Write(buffer, 0, strBuffer.Length); //Send it + helloNeighbourRequest.ContentLength = buffer.Length; + using (var os = helloNeighbourRequest.GetRequestStream()) + os.Write(buffer, 0, buffer.Length); + buffer = null; //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); } -// catch (Exception e) + // catch (Exception e) catch { -// m_log.WarnFormat( -// "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", -// thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); + //m_log.WarnFormat( + // "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", + // thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); return false; } - finally - { - if (os != null) - os.Dispose(); - } - // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall"); @@ -173,34 +147,22 @@ namespace OpenSim.Services.Connectors { using (WebResponse webResponse = helloNeighbourRequest.GetResponse()) { - if (webResponse == null) + using (StreamReader sr = new StreamReader(webResponse.GetResponseStream())) { - m_log.DebugFormat( - "[NEIGHBOUR SERVICES CONNECTOR]: Null reply on DoHelloNeighbourCall post from {0} to {1}", - thisRegion.RegionName, region.RegionName); - } - - using (Stream s = webResponse.GetResponseStream()) - { - using (StreamReader sr = new StreamReader(s)) - { - sr.ReadToEnd(); // just try to read - //reply = sr.ReadToEnd().Trim(); - //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); - } + sr.ReadToEnd(); // just try to read + //reply = sr.ReadToEnd().Trim(); + //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); } } + return true; } catch (Exception e) { m_log.Warn(string.Format( "[NEIGHBOUR SERVICES CONNECTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2} ", region.RegionName, thisRegion.RegionName, e.Message), e); - - return false; } - - return true; + return false; } } }