From beef41f24cfdc57e584d19beed423cba83b7f829 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Jan 2015 19:40:17 +0000 Subject: [PATCH] Stop simulators attempting to contact registered but offline regions (RegionFlags.Persistent but not RegioNFlags.RegionOnline) on startup and when an avatar completes a teleport. This eliminates spurious network calls and failure reporting. This is done by adding RegionFlags to the GridRegion returned data in a backward compatible way as an alternative to multiple IGridService.GetRegionFlags() calls Using a simulator or a grid service older than this commit will just see previous behaviour. --- .../EntityTransfer/EntityTransferModule.cs | 39 ++-- .../Scenes/SceneCommunicationService.cs | 27 ++- OpenSim/Services/Interfaces/IGridService.cs | 216 ++++++++++-------- 3 files changed, 168 insertions(+), 114 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index cb32eec31f..089bd4f53d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1924,7 +1924,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_regionInfo != null) { - neighbours = RequestNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); + neighbours = GetNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); } else { @@ -2364,16 +2364,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } /// - /// Return the list of regions that are considered to be neighbours to the given scene. + /// Return the list of online regions that are considered to be neighbours to the given scene. /// - /// + /// /// /// /// - protected List RequestNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) + protected List GetNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) { Scene pScene = avatar.Scene; RegionInfo m_regionInfo = pScene.RegionInfo; + List neighbours; // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't // clear what should be done with a "far view" given that megaregions already extended the @@ -2391,27 +2392,35 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer uint endX = Util.RegionToWorldLoc(pRegionLocX) + dd + Constants.RegionSize/2; uint endY = Util.RegionToWorldLoc(pRegionLocY) + dd + Constants.RegionSize/2; - List neighbours = - avatar.Scene.GridService.GetRegionRange(m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); - - neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); - return neighbours; + neighbours + = avatar.Scene.GridService.GetRegionRange( + m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); } else { Vector2 swCorner, neCorner; GetMegaregionViewRange(out swCorner, out neCorner); - List neighbours + neighbours = pScene.GridService.GetRegionRange( m_regionInfo.ScopeID, (int)Util.RegionToWorldLoc((uint)swCorner.X), (int)Util.RegionToWorldLoc((uint)neCorner.X), - (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y) ); - - neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); - - return neighbours; + (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y)); } + +// neighbours.ForEach( +// n => +// m_log.DebugFormat( +// "[ENTITY TRANSFER MODULE]: Region flags for {0} as seen by {1} are {2}", +// n.RegionName, Scene.Name, n.RegionFlags != null ? n.RegionFlags.ToString() : "not present")); + + // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1). + neighbours.RemoveAll( + r => + r.RegionID == m_regionInfo.RegionID + || (r.RegionFlags != null && (r.RegionFlags & OpenSim.Framework.RegionFlags.RegionOnline) == 0)); + + return neighbours; } private List NewNeighbours(List currentNeighbours, List previousNeighbours) diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 9db5309624..810176848f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -109,9 +109,34 @@ namespace OpenSim.Region.Framework.Scenes List neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); - m_log.DebugFormat("{0} Informing {1} neighbours that region {2} is up", LogHeader, neighbours.Count, m_scene.Name); + 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"); + + // 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 ((regionFlags & OpenSim.Framework.RegionFlags.RegionOnline) != 0) + onlineNeighbours.Add(n); + } + else + { + onlineNeighbours.Add(n); + } + } + + m_log.DebugFormat( + "{0} Informing {1} neighbours that region {2} is up", + LogHeader, onlineNeighbours.Count, m_scene.Name); + + foreach (GridRegion n in onlineNeighbours) { InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; d.BeginInvoke(neighbourService, region, n.RegionHandle, diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index ce50ab001c..0b318b3195 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -179,6 +179,17 @@ namespace OpenSim.Services.Interfaces } protected string m_regionName = String.Empty; + /// + /// Region flags. + /// + /// + /// If not set (chiefly if a robust service is running code pre OpenSim 0.8.1) then this will be null and + /// should be ignored. If you require flags information please use the separate IGridService.GetRegionFlags() call + /// XXX: This field is currently ignored when used in RegisterRegion, but could potentially be + /// used to set flags at this point. + /// + public OpenSim.Framework.RegionFlags? RegionFlags { get; set; } + protected string m_externalHostName; protected IPEndPoint m_internalEndPoint; @@ -299,6 +310,7 @@ namespace OpenSim.Services.Interfaces public GridRegion(GridRegion ConvertFrom) { m_regionName = ConvertFrom.RegionName; + RegionFlags = ConvertFrom.RegionFlags; m_regionLocX = ConvertFrom.RegionLocX; m_regionLocY = ConvertFrom.RegionLocY; RegionSizeX = ConvertFrom.RegionSizeX; @@ -315,8 +327,112 @@ namespace OpenSim.Services.Interfaces RegionSecret = ConvertFrom.RegionSecret; EstateOwner = ConvertFrom.EstateOwner; } + + public GridRegion(Dictionary kvp) + { + if (kvp.ContainsKey("uuid")) + RegionID = new UUID((string)kvp["uuid"]); - # region Definition of equality + if (kvp.ContainsKey("locX")) + RegionLocX = Convert.ToInt32((string)kvp["locX"]); + + if (kvp.ContainsKey("locY")) + RegionLocY = Convert.ToInt32((string)kvp["locY"]); + + if (kvp.ContainsKey("sizeX")) + RegionSizeX = Convert.ToInt32((string)kvp["sizeX"]); + else + RegionSizeX = (int)Constants.RegionSize; + + if (kvp.ContainsKey("sizeY")) + RegionSizeY = Convert.ToInt32((string)kvp["sizeY"]); + else + RegionSizeX = (int)Constants.RegionSize; + + if (kvp.ContainsKey("regionName")) + RegionName = (string)kvp["regionName"]; + + if (kvp.ContainsKey("flags") && kvp["flags"] != null) + RegionFlags = (OpenSim.Framework.RegionFlags?)Convert.ToInt32((string)kvp["flags"]); + + if (kvp.ContainsKey("serverIP")) + { + //int port = 0; + //Int32.TryParse((string)kvp["serverPort"], out port); + //IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["serverIP"]), port); + ExternalHostName = (string)kvp["serverIP"]; + } + else + ExternalHostName = "127.0.0.1"; + + if (kvp.ContainsKey("serverPort")) + { + Int32 port = 0; + Int32.TryParse((string)kvp["serverPort"], out port); + InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port); + } + + if (kvp.ContainsKey("serverHttpPort")) + { + UInt32 port = 0; + UInt32.TryParse((string)kvp["serverHttpPort"], out port); + HttpPort = port; + } + + if (kvp.ContainsKey("serverURI")) + ServerURI = (string)kvp["serverURI"]; + + if (kvp.ContainsKey("regionMapTexture")) + UUID.TryParse((string)kvp["regionMapTexture"], out TerrainImage); + + if (kvp.ContainsKey("parcelMapTexture")) + UUID.TryParse((string)kvp["parcelMapTexture"], out ParcelImage); + + if (kvp.ContainsKey("access")) + Access = Byte.Parse((string)kvp["access"]); + + if (kvp.ContainsKey("regionSecret")) + RegionSecret =(string)kvp["regionSecret"]; + + if (kvp.ContainsKey("owner_uuid")) + EstateOwner = new UUID(kvp["owner_uuid"].ToString()); + + if (kvp.ContainsKey("Token")) + Token = kvp["Token"].ToString(); + + // m_log.DebugFormat("{0} New GridRegion. id={1}, loc=<{2},{3}>, size=<{4},{5}>", + // LogHeader, RegionID, RegionLocX, RegionLocY, RegionSizeX, RegionSizeY); + } + + public Dictionary ToKeyValuePairs() + { + Dictionary kvp = new Dictionary(); + kvp["uuid"] = RegionID.ToString(); + kvp["locX"] = RegionLocX.ToString(); + kvp["locY"] = RegionLocY.ToString(); + kvp["sizeX"] = RegionSizeX.ToString(); + kvp["sizeY"] = RegionSizeY.ToString(); + kvp["regionName"] = RegionName; + + if (RegionFlags != null) + kvp["flags"] = ((int)RegionFlags).ToString(); + + kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString(); + kvp["serverHttpPort"] = HttpPort.ToString(); + kvp["serverURI"] = ServerURI; + kvp["serverPort"] = InternalEndPoint.Port.ToString(); + kvp["regionMapTexture"] = TerrainImage.ToString(); + kvp["parcelMapTexture"] = ParcelImage.ToString(); + kvp["access"] = Access.ToString(); + kvp["regionSecret"] = RegionSecret; + kvp["owner_uuid"] = EstateOwner.ToString(); + kvp["Token"] = Token.ToString(); + // Maturity doesn't seem to exist in the DB + + return kvp; + } + + #region Definition of equality /// /// Define equality as two regions having the same, non-zero UUID. @@ -403,101 +519,5 @@ namespace OpenSim.Services.Interfaces { get { return Util.UIntsToLong((uint)RegionLocX, (uint)RegionLocY); } } - - public Dictionary ToKeyValuePairs() - { - Dictionary kvp = new Dictionary(); - kvp["uuid"] = RegionID.ToString(); - kvp["locX"] = RegionLocX.ToString(); - kvp["locY"] = RegionLocY.ToString(); - kvp["sizeX"] = RegionSizeX.ToString(); - kvp["sizeY"] = RegionSizeY.ToString(); - kvp["regionName"] = RegionName; - kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString(); - kvp["serverHttpPort"] = HttpPort.ToString(); - kvp["serverURI"] = ServerURI; - kvp["serverPort"] = InternalEndPoint.Port.ToString(); - kvp["regionMapTexture"] = TerrainImage.ToString(); - kvp["parcelMapTexture"] = ParcelImage.ToString(); - kvp["access"] = Access.ToString(); - kvp["regionSecret"] = RegionSecret; - kvp["owner_uuid"] = EstateOwner.ToString(); - kvp["Token"] = Token.ToString(); - // Maturity doesn't seem to exist in the DB - return kvp; - } - - public GridRegion(Dictionary kvp) - { - if (kvp.ContainsKey("uuid")) - RegionID = new UUID((string)kvp["uuid"]); - - if (kvp.ContainsKey("locX")) - RegionLocX = Convert.ToInt32((string)kvp["locX"]); - - if (kvp.ContainsKey("locY")) - RegionLocY = Convert.ToInt32((string)kvp["locY"]); - - if (kvp.ContainsKey("sizeX")) - RegionSizeX = Convert.ToInt32((string)kvp["sizeX"]); - else - RegionSizeX = (int)Constants.RegionSize; - - if (kvp.ContainsKey("sizeY")) - RegionSizeY = Convert.ToInt32((string)kvp["sizeY"]); - else - RegionSizeX = (int)Constants.RegionSize; - - if (kvp.ContainsKey("regionName")) - RegionName = (string)kvp["regionName"]; - - if (kvp.ContainsKey("serverIP")) - { - //int port = 0; - //Int32.TryParse((string)kvp["serverPort"], out port); - //IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["serverIP"]), port); - ExternalHostName = (string)kvp["serverIP"]; - } - else - ExternalHostName = "127.0.0.1"; - - if (kvp.ContainsKey("serverPort")) - { - Int32 port = 0; - Int32.TryParse((string)kvp["serverPort"], out port); - InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port); - } - - if (kvp.ContainsKey("serverHttpPort")) - { - UInt32 port = 0; - UInt32.TryParse((string)kvp["serverHttpPort"], out port); - HttpPort = port; - } - - if (kvp.ContainsKey("serverURI")) - ServerURI = (string)kvp["serverURI"]; - - if (kvp.ContainsKey("regionMapTexture")) - UUID.TryParse((string)kvp["regionMapTexture"], out TerrainImage); - - if (kvp.ContainsKey("parcelMapTexture")) - UUID.TryParse((string)kvp["parcelMapTexture"], out ParcelImage); - - if (kvp.ContainsKey("access")) - Access = Byte.Parse((string)kvp["access"]); - - if (kvp.ContainsKey("regionSecret")) - RegionSecret =(string)kvp["regionSecret"]; - - if (kvp.ContainsKey("owner_uuid")) - EstateOwner = new UUID(kvp["owner_uuid"].ToString()); - - if (kvp.ContainsKey("Token")) - Token = kvp["Token"].ToString(); - - // m_log.DebugFormat("{0} New GridRegion. id={1}, loc=<{2},{3}>, size=<{4},{5}>", - // LogHeader, RegionID, RegionLocX, RegionLocY, RegionSizeX, RegionSizeY); - } } -} +} \ No newline at end of file