Merge branch 'master' into httptests

httptests
UbitUmarov 2016-07-30 20:13:16 +01:00
commit cb23d1bf24
7 changed files with 182 additions and 299 deletions

View File

@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]"; private static string LogHeader = "[LOCAL GRID SERVICE CONNECTOR]";
private IGridService m_GridService; private IGridService m_GridService;
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>(); private RegionInfoCache m_RegionInfoCache = null;
private bool m_Enabled; private bool m_Enabled;
@ -60,10 +60,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
m_log.DebugFormat("{0} LocalGridServicesConnector no parms.", LogHeader); m_log.DebugFormat("{0} LocalGridServicesConnector no parms.", LogHeader);
} }
public LocalGridServicesConnector(IConfigSource source) public LocalGridServicesConnector(IConfigSource source, RegionInfoCache regionInfoCache)
{ {
m_log.DebugFormat("{0} LocalGridServicesConnector instantiated directly.", LogHeader); m_log.DebugFormat("{0} LocalGridServicesConnector instantiated directly.", LogHeader);
InitialiseService(source); InitialiseService(source, regionInfoCache);
} }
#region ISharedRegionModule #region ISharedRegionModule
@ -86,19 +86,25 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
string name = moduleConfig.GetString("GridServices", ""); string name = moduleConfig.GetString("GridServices", "");
if (name == Name) if (name == Name)
{ {
InitialiseService(source);
if(InitialiseService(source,null))
m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled");
} }
} }
} }
private void InitialiseService(IConfigSource source) private bool InitialiseService(IConfigSource source, RegionInfoCache ric)
{ {
if(ric == null)
m_RegionInfoCache = new RegionInfoCache();
else
m_RegionInfoCache = ric;
IConfig config = source.Configs["GridService"]; IConfig config = source.Configs["GridService"];
if (config == null) if (config == null)
{ {
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini"); m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini");
return; return false;
} }
string serviceDll = config.GetString("LocalServiceModule", String.Empty); string serviceDll = config.GetString("LocalServiceModule", String.Empty);
@ -106,7 +112,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (serviceDll == String.Empty) if (serviceDll == String.Empty)
{ {
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService"); m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService");
return; return false;
} }
Object[] args = new Object[] { source }; Object[] args = new Object[] { source };
@ -117,10 +123,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (m_GridService == null) if (m_GridService == null)
{ {
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service"); m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service");
return; return false;
} }
m_Enabled = true; m_Enabled = true;
return true;
} }
public void PostInitialise() public void PostInitialise()
@ -143,13 +150,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
scene.RegisterModuleInterface<IGridService>(this); scene.RegisterModuleInterface<IGridService>(this);
lock (m_LocalCache) m_RegionInfoCache.CacheLocal(new GridRegion(scene.RegionInfo));
{ scene.EventManager.OnRegionUp += OnRegionUp;
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
else
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
}
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -157,11 +159,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (!m_Enabled) if (!m_Enabled)
return; return;
lock (m_LocalCache) m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionID);
{ scene.EventManager.OnRegionUp -= OnRegionUp;
m_LocalCache[scene.RegionInfo.RegionID].Clear();
m_LocalCache.Remove(scene.RegionInfo.RegionID);
}
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -172,6 +171,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
#region IGridService #region IGridService
private void OnRegionUp(GridRegion region)
{
// This shouldn't happen
if (region == null)
return;
m_RegionInfoCache.CacheNearNeighbour(region.ScopeID, region);
}
public string RegisterRegion(UUID scopeID, GridRegion regionInfo) public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
{ {
return m_GridService.RegisterRegion(scopeID, regionInfo); return m_GridService.RegisterRegion(scopeID, regionInfo);
@ -189,7 +197,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
{ {
return m_GridService.GetRegionByUUID(scopeID, regionID); bool inCache = false;
GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache);
if (inCache)
return rinfo;
rinfo = m_GridService.GetRegionByUUID(scopeID, regionID);
if(rinfo != null)
m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo;
} }
// Get a region given its base coordinates. // Get a region given its base coordinates.
@ -197,52 +213,37 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
// be the base coordinate of the region. // be the base coordinate of the region.
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
{ {
GridRegion region = null; // try in cache by handler first
uint regionX = Util.WorldToRegionLoc((uint)x); ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y);
uint regionY = Util.WorldToRegionLoc((uint)y);
// First see if it's a neighbour, even if it isn't on this sim. bool inCache = false;
// Neighbour data is cached in memory, so this is fast GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache);
if (inCache)
return rinfo;
lock (m_LocalCache) // try in cache by slower position next
{ rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache);
foreach (RegionCache rcache in m_LocalCache.Values) if (inCache)
{ return rinfo;
region = rcache.GetRegionByPosition(x, y);
if (region != null)
{
//m_log.DebugFormat("{0} GetRegionByPosition. Found region {1} in cache (of region {2}). Pos=<{3},{4}>",
// LogHeader, region.RegionName, rcache.RegionName,
// Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
break;
}
}
}
// Then try on this sim (may be a lookup in DB if this is using MySql). // Then try on this sim (may be a lookup in DB if this is using MySql).
if (region == null) rinfo = m_GridService.GetRegionByPosition(scopeID, x, y);
{ if(rinfo != null)
region = m_GridService.GetRegionByPosition(scopeID, x, y); m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo;
if (region == null)
{
m_log.DebugFormat("{0} GetRegionByPosition. Region not found by grid service. Pos=<{1},{2}>",
LogHeader, regionX, regionY);
}
else
{
m_log.DebugFormat("{0} GetRegionByPosition. Got region {1} from grid service. Pos=<{2},{3}>",
LogHeader, region.RegionName,
Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
}
}
return region;
} }
public GridRegion GetRegionByName(UUID scopeID, string regionName) public GridRegion GetRegionByName(UUID scopeID, string regionName)
{ {
return m_GridService.GetRegionByName(scopeID, regionName); bool inCache = false;
GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionName, out inCache);
if (inCache)
return rinfo;
rinfo = m_GridService.GetRegionByName(scopeID, regionName);
if(rinfo != null)
m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo;
} }
public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
@ -290,7 +291,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void HandleShowNeighboursCommand(string module, string[] cmdparams) public void HandleShowNeighboursCommand(string module, string[] cmdparams)
{ {
System.Text.StringBuilder caps = new System.Text.StringBuilder(); System.Text.StringBuilder caps = new System.Text.StringBuilder();
/* temporary broken
lock (m_LocalCache) lock (m_LocalCache)
{ {
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache) foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
@ -303,6 +304,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
} }
MainConsole.Instance.Output(caps.ToString()); MainConsole.Instance.Output(caps.ToString());
*/
MainConsole.Instance.Output("Neighbours list not avaiable in this version\n");
} }
} }
} }

View File

@ -1,103 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenMetaverse;
using log4net;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{
public class RegionCache
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private Dictionary<ulong, GridRegion> m_neighbours = new Dictionary<ulong, GridRegion>();
public string RegionName
{
get { return m_scene.RegionInfo.RegionName; }
}
public RegionCache(Scene s)
{
m_scene = s;
m_scene.EventManager.OnRegionUp += OnRegionUp;
}
private void OnRegionUp(GridRegion otherRegion)
{
// This shouldn't happen
if (otherRegion == null)
return;
m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}",
m_scene.RegionInfo.RegionName, otherRegion.RegionName, Util.WorldToRegionLoc((uint)otherRegion.RegionLocX), Util.WorldToRegionLoc((uint)otherRegion.RegionLocY));
m_neighbours[otherRegion.RegionHandle] = otherRegion;
}
public void Clear()
{
m_scene.EventManager.OnRegionUp -= OnRegionUp;
m_neighbours.Clear();
}
public List<GridRegion> GetNeighbours()
{
return new List<GridRegion>(m_neighbours.Values);
}
public GridRegion GetRegionByPosition(int x, int y)
{
// do actual search by position
// not the best, but this will not hold that many regions
GridRegion foundRegion = null;
foreach(GridRegion r in m_neighbours.Values)
{
if (x >= r.RegionLocX && x < r.RegionLocX + r.RegionSizeX
&& y >= r.RegionLocY && y < r.RegionLocY + r.RegionSizeY)
{
foundRegion = r;
break;
}
}
return foundRegion;
}
}
}

View File

@ -59,26 +59,42 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void Cache(UUID scopeID, GridRegion rinfo) public void Cache(UUID scopeID, GridRegion rinfo)
{ {
// for now, do not cache negative results; this is because
// we need to figure out how to handle regions coming online
// in a timely way
if (rinfo == null) if (rinfo == null)
return; return;
m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS);
} }
public void CacheLocal(GridRegion rinfo)
{
if (rinfo == null)
return;
m_Cache.AddOrUpdate(rinfo.ScopeID, rinfo, 1e7f);
}
public void CacheNearNeighbour(UUID scopeID, GridRegion rinfo)
{
if (rinfo == null)
return;
// m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS);
m_Cache.Add(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); // don't override local regions
}
public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds) public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds)
{ {
// for now, do not cache negative results; this is because
// we need to figure out how to handle regions coming online
// in a timely way
if (rinfo == null) if (rinfo == null)
return; return;
m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds); m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds);
} }
public void Remove(UUID scopeID, UUID regionID)
{
m_Cache.Remove(scopeID, regionID);
}
public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
{ {
inCache = false; inCache = false;
@ -134,43 +150,47 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return null; return null;
} }
} }
// following code partialy adapted from lib OpenMetaverse // following code partialy adapted from lib OpenMetaverse
public class RegionKey : IComparable<RegionKey> public class RegionKey
{ {
private UUID m_scopeID; public UUID ScopeID;
private UUID m_RegionID; public UUID RegionID;
private DateTime m_expirationDate;
public RegionKey(UUID scopeID, UUID id) public RegionKey(UUID scopeID, UUID id)
{ {
m_scopeID = scopeID; ScopeID = scopeID;
m_RegionID = id; RegionID = id;
} }
public UUID ScopeID public override int GetHashCode()
{ {
get { return m_scopeID; } int hash = ScopeID.GetHashCode();
} hash += hash * 23 + RegionID.GetHashCode();
public DateTime ExpirationDate
{
get { return m_expirationDate; }
set { m_expirationDate = value; }
}
public int GetHaskCode()
{
int hash = m_scopeID.GetHashCode();
hash += hash * 23 + m_RegionID.GetHashCode();
return hash; return hash;
} }
public int CompareTo(RegionKey other) public override bool Equals(Object b)
{ {
return GetHashCode().CompareTo(other.GetHashCode()); if(b == null)
return false;
RegionKey kb = b as RegionKey;
return (ScopeID == kb.ScopeID && RegionID == kb.RegionID);
}
}
class RegionKeyEqual : EqualityComparer<RegionKey>
{
public override int GetHashCode(RegionKey rk)
{
return rk.GetHashCode();
}
public override bool Equals(RegionKey a, RegionKey b)
{
return (a.ScopeID == b.ScopeID && a.RegionID == b.RegionID);
} }
} }
@ -246,7 +266,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
} }
} }
public sealed class RegionsExpiringCache public class RegionsExpiringCache
{ {
const double CACHE_PURGE_HZ = 60; // seconds const double CACHE_PURGE_HZ = 60; // seconds
const int MAX_LOCK_WAIT = 10000; // milliseconds const int MAX_LOCK_WAIT = 10000; // milliseconds
@ -256,7 +276,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
/// <summary>For thread safety</summary> /// <summary>For thread safety</summary>
object isPurging = new object(); object isPurging = new object();
Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>(); static RegionKeyEqual keyequal = new RegionKeyEqual();
Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>(keyequal);
Dictionary<RegionKey, DateTime> timedExpires = new Dictionary<RegionKey, DateTime>();
Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>(); Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>();
private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds);
@ -278,8 +300,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (timedStorage.ContainsKey(key)) if (timedStorage.ContainsKey(key))
return false; return false;
key.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
timedStorage.Add(key, region); timedStorage[key] = region;
timedExpires[key] = expire;
RegionInfoByScope ris = null; RegionInfoByScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
@ -303,12 +326,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
try try
{ {
RegionKey key = new RegionKey(scope, region.RegionID); RegionKey key = new RegionKey(scope, region.RegionID);
key.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
if (timedStorage.ContainsKey(key)) if (timedStorage.ContainsKey(key))
{ {
timedStorage.Remove(key); timedStorage[key] = region;
timedStorage.Add(key, region); if(expire > timedExpires[key])
timedExpires[key] = expire;
if(!InfobyScope.ContainsKey(scope)) if(!InfobyScope.ContainsKey(scope))
{ {
@ -319,7 +343,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
} }
else else
{ {
timedStorage.Add(key, region); timedStorage[key] = region;
timedExpires[key] = expire;
RegionInfoByScope ris = null; RegionInfoByScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
{ {
@ -341,6 +366,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
try try
{ {
timedStorage.Clear(); timedStorage.Clear();
timedExpires.Clear();
InfobyScope.Clear(); InfobyScope.Clear();
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
@ -370,10 +396,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return timedStorage.Count; return timedStorage.Count;
} }
} }
public bool Remove(UUID scope, GridRegion region) public bool Remove(UUID scope, GridRegion region)
{ {
RegionKey key = new RegionKey(scope, region.RegionID); return Remove(scope, region.RegionID);
}
public bool Remove(UUID scope, UUID regionID)
{
RegionKey key = new RegionKey(scope, regionID);
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
@ -391,6 +420,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
InfobyScope.Remove(scope); InfobyScope.Remove(scope);
} }
timedStorage.Remove(key); timedStorage.Remove(key);
timedExpires.Remove(key);
return true; return true;
} }
else else
@ -544,9 +574,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (!timedStorage.ContainsKey(key)) if (!timedStorage.ContainsKey(key))
return false; return false;
timedStorage.Remove(key); DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
key.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); timedStorage[key] = region;
timedStorage.Add(key, region); if(expire > timedExpires[key])
timedExpires[key] = expire;
return true; return true;
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
@ -572,26 +604,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return; return;
try try
{ {
OpenMetaverse.Lazy<List<object>> expiredItems = new OpenMetaverse.Lazy<List<object>>(); List<RegionKey> expiredkeys = new List<RegionKey>();
foreach (RegionKey timedKey in timedStorage.Keys) foreach (KeyValuePair<RegionKey, DateTime> kvp in timedExpires)
{ {
if (timedKey.ExpirationDate < signalTime) if (kvp.Value < signalTime)
{ expiredkeys.Add(kvp.Key);
// Mark the object for purge
expiredItems.Value.Add(timedKey);
}
else
{
break;
}
} }
if (expiredkeys.Count > 0)
{
RegionInfoByScope ris; RegionInfoByScope ris;
if (expiredItems.IsValueCreated) foreach (RegionKey key in expiredkeys)
{
foreach (RegionKey key in expiredItems.Value)
{ {
ris = null; ris = null;
if(InfobyScope.TryGetValue(key.ScopeID, out ris) && ris != null) if(InfobyScope.TryGetValue(key.ScopeID, out ris) && ris != null)
@ -604,6 +628,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
InfobyScope.Remove(key.ScopeID); InfobyScope.Remove(key.ScopeID);
} }
timedStorage.Remove(key); timedStorage.Remove(key);
timedExpires.Remove(key);
} }
} }
} }

View File

@ -87,38 +87,46 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
string name = moduleConfig.GetString("GridServices", ""); string name = moduleConfig.GetString("GridServices", "");
if (name == Name) if (name == Name)
{ {
InitialiseServices(source); if(InitialiseServices(source))
{
m_Enabled = true; m_Enabled = true;
m_log.Info("[REMOTE GRID CONNECTOR]: Remote grid enabled"); m_log.Info("[REMOTE GRID CONNECTOR]: Remote grid enabled");
} }
} }
} }
}
private void InitialiseServices(IConfigSource source) private bool InitialiseServices(IConfigSource source)
{ {
IConfig gridConfig = source.Configs["GridService"]; IConfig gridConfig = source.Configs["GridService"];
if (gridConfig == null) if (gridConfig == null)
{ {
m_log.Error("[REMOTE GRID CONNECTOR]: GridService missing from OpenSim.ini"); m_log.Error("[REMOTE GRID CONNECTOR]: GridService missing from OpenSim.ini");
return; return false;
} }
string networkConnector = gridConfig.GetString("NetworkConnector", string.Empty); string networkConnector = gridConfig.GetString("NetworkConnector", string.Empty);
if (networkConnector == string.Empty) if (networkConnector == string.Empty)
{ {
m_log.Error("[REMOTE GRID CONNECTOR]: Please specify a network connector under [GridService]"); m_log.Error("[REMOTE GRID CONNECTOR]: Please specify a network connector under [GridService]");
return; return false;
} }
Object[] args = new Object[] { source }; Object[] args = new Object[] { source };
m_RemoteGridService = ServerUtils.LoadPlugin<IGridService>(networkConnector, args); m_RemoteGridService = ServerUtils.LoadPlugin<IGridService>(networkConnector, args);
m_LocalGridService = new LocalGridServicesConnector(source); m_LocalGridService = new LocalGridServicesConnector(source, m_RegionInfoCache);
if (m_LocalGridService == null)
{
m_log.Error("[REMOTE GRID CONNECTOR]: failed to loar local connector");
return false;
}
return true;
} }
public void PostInitialise() public void PostInitialise()
{ {
if (m_LocalGridService != null)
((ISharedRegionModule)m_LocalGridService).PostInitialise(); ((ISharedRegionModule)m_LocalGridService).PostInitialise();
} }
@ -131,13 +139,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (m_Enabled) if (m_Enabled)
scene.RegisterModuleInterface<IGridService>(this); scene.RegisterModuleInterface<IGridService>(this);
if (m_LocalGridService != null)
((ISharedRegionModule)m_LocalGridService).AddRegion(scene); ((ISharedRegionModule)m_LocalGridService).AddRegion(scene);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (m_LocalGridService != null)
((ISharedRegionModule)m_LocalGridService).RemoveRegion(scene); ((ISharedRegionModule)m_LocalGridService).RemoveRegion(scene);
} }
@ -174,15 +180,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
{ {
bool inCache = false; GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache); if (rinfo != null)
if (inCache)
return rinfo; return rinfo;
rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
if (rinfo == null)
rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID);
m_RegionInfoCache.Cache(scopeID, rinfo); m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo; return rinfo;
} }
@ -193,25 +195,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
// The coordinates are world coords (meters), NOT region units. // The coordinates are world coords (meters), NOT region units.
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
{ {
// try in cache by handler first GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); if (rinfo != null)
{
bool inCache = false; m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache from local. Pos=<{1},{2}>, RegionHandle={3}",
GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
if (inCache)
return rinfo; return rinfo;
}
// try in cache by slower position next
rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache);
if (inCache)
return rinfo;
rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
if (rinfo == null)
rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y); rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y);
if (rinfo == null) if (rinfo == null)
{ {
uint regionX = Util.WorldToRegionLoc((uint)x); uint regionX = Util.WorldToRegionLoc((uint)x);
@ -223,23 +216,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
m_RegionInfoCache.Cache(scopeID, rinfo); m_RegionInfoCache.Cache(scopeID, rinfo);
m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}",
rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, (rinfo == null) ? regionHandle : rinfo.RegionHandle); rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
} }
return rinfo; return rinfo;
} }
public GridRegion GetRegionByName(UUID scopeID, string regionName) public GridRegion GetRegionByName(UUID scopeID, string regionName)
{ {
bool inCache = false; GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName);
GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionName, out inCache); if (rinfo != null)
if (inCache)
return rinfo; return rinfo;
rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName);
if (rinfo == null)
rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName);
// can't cache negative results for name lookups
m_RegionInfoCache.Cache(scopeID, rinfo); m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo; return rinfo;
} }

View File

@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion"); config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion");
config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion"); config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion");
m_LocalConnector = new LocalGridServicesConnector(config); m_LocalConnector = new LocalGridServicesConnector(config, null);
} }
/// <summary> /// <summary>

View File

@ -31,21 +31,6 @@
SimulationServiceInConnector = true SimulationServiceInConnector = true
LibraryModule = true LibraryModule = true
[SimulationService]
; This is the protocol version which the simulator advertises to the source destination when acting as a target destination for a teleport
; It is used to control the teleport handoff process.
; Valid values are
; "SIMULATION/0.3"
; - This is the default, and it supports teleports to variable-sized regions
; - Older versions can teleport to this one, but only if the destination region
; is 256x256
; "SIMULATION/0.2"
; - A source simulator which only implements "SIMULATION/0.1" can still teleport with that protocol
; - this protocol is more efficient than "SIMULATION/0.1"
; "SIMULATION/0.1"
; - this is an older teleport protocol used in OpenSimulator 0.7.5 and before.
ConnectorProtocolVersion = "SIMULATION/0.3"
[SimulationDataStore] [SimulationDataStore]
LocalServiceModule = "OpenSim.Services.SimulationService.dll:SimulationDataService" LocalServiceModule = "OpenSim.Services.SimulationService.dll:SimulationDataService"

View File

@ -36,21 +36,6 @@
SimulationServiceInConnector = true SimulationServiceInConnector = true
LibraryModule = true LibraryModule = true
[SimulationService]
; This is the protocol version which the simulator advertises to the source destination when acting as a target destination for a teleport
; It is used to control the teleport handoff process.
; Valid values are
; "SIMULATION/0.3"
; - This is the default, and it supports teleports to variable-sized regions
; - Older versions can teleport to this one, but only if the destination region
; is 256x256
; "SIMULATION/0.2"
; - A source simulator which only implements "SIMULATION/0.1" can still teleport with that protocol
; - this protocol is more efficient than "SIMULATION/0.1"
; "SIMULATION/0.1"
; - this is an older teleport protocol used in OpenSimulator 0.7.5 and before.
ConnectorProtocolVersion = "SIMULATION/0.3"
[Profile] [Profile]
Module = "BasicProfileModule" Module = "BasicProfileModule"