diff --git a/OpenSim/Capabilities/Handlers/GetAssets/GetAssetsHandler.cs b/OpenSim/Capabilities/Handlers/GetAssets/GetAssetsHandler.cs
index 96b27dbb13..bacccd063f 100644
--- a/OpenSim/Capabilities/Handlers/GetAssets/GetAssetsHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetAssets/GetAssetsHandler.cs
@@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
+using System.Threading;
using log4net;
using Nini.Config;
using OpenMetaverse;
@@ -122,7 +123,18 @@ namespace OpenSim.Capabilities.Handlers
if(!UUID.TryParse(assetStr, out assetID))
return;
- AssetBase asset = m_assetService.Get(assetID.ToString(), serviceURL, false);
+ ManualResetEventSlim done = new ManualResetEventSlim(false);
+ AssetBase asset = null;
+ m_assetService.Get(assetID.ToString(), serviceURL, false, (AssetBase a) =>
+ {
+ asset = a;
+ done.Set();
+ });
+
+ done.Wait();
+ done.Dispose();
+ done = null;
+
if (asset == null)
{
// m_log.Warn("[GETASSET]: not found: " + query + " " + assetStr);
diff --git a/OpenSim/Framework/IAssetCache.cs b/OpenSim/Framework/IAssetCache.cs
index 1cf7ca5a0c..9105f35ec2 100644
--- a/OpenSim/Framework/IAssetCache.cs
+++ b/OpenSim/Framework/IAssetCache.cs
@@ -53,6 +53,8 @@ namespace OpenSim.Framework
// as get without negative cache check
AssetBase GetCached(string id);
+ bool GetFromMemory(string id, out AssetBase asset);
+
///
/// Check whether an asset with the specified id exists in the cache.
///
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 87791cb15c..291f2d2e99 100755
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -313,10 +313,10 @@ namespace OpenSim.Region.CoreModules.Asset
if (m_FileCacheEnabled && m_assetFileWriteWorker == null)
{
- m_assetFileWriteWorker = new ObjectJobEngine(ProcessWrites, "FloatsamCacheWriter", 1000 , 1);
+ m_assetFileWriteWorker = new ObjectJobEngine(ProcessWrites, "FloatsamCacheWriter", 1000, 1);
}
- if(!string.IsNullOrWhiteSpace(m_assetLoader) && scene.RegionInfo.RegionID == m_Scenes[0].RegionInfo.RegionID)
+ if (!string.IsNullOrWhiteSpace(m_assetLoader) && scene.RegionInfo.RegionID == m_Scenes[0].RegionInfo.RegionID)
{
IAssetLoader assetLoader = ServerUtils.LoadPlugin(m_assetLoader, new object[] { });
if (assetLoader != null)
@@ -341,11 +341,11 @@ namespace OpenSim.Region.CoreModules.Asset
try
{
WriteAssetInfo wai = (WriteAssetInfo)o;
- WriteFileCache(wai.filename,wai.asset,wai.replace);
+ WriteFileCache(wai.filename, wai.asset, wai.replace);
wai.asset = null;
Thread.Yield();
}
- catch{ }
+ catch { }
}
////////////////////////////////////////////////////////////
@@ -644,6 +644,48 @@ namespace OpenSim.Region.CoreModules.Asset
return true;
}
+ public bool GetFromMemory(string id, out AssetBase asset)
+ {
+ asset = null;
+
+ m_Requests++;
+
+ if (id.Equals(Util.UUIDZeroString))
+ return false;
+
+ if (m_negativeCache.ContainsKey(id))
+ return false;
+
+ asset = GetFromWeakReference(id);
+ if (asset != null)
+ {
+ if (m_updateFileTimeOnCacheHit)
+ {
+ string filename = GetFileName(id);
+ UpdateFileLastAccessTime(filename);
+ }
+ if (m_MemoryCacheEnabled)
+ UpdateMemoryCache(id, asset);
+ return true;
+ }
+
+ if (m_MemoryCacheEnabled)
+ {
+ asset = GetFromMemoryCache(id);
+ if (asset != null)
+ {
+ UpdateWeakReference(id, asset);
+ if (m_updateFileTimeOnCacheHit)
+ {
+ string filename = GetFileName(id);
+ UpdateFileLastAccessTime(filename);
+ }
+ return true;
+ }
+ }
+ return true;
+ }
+
public bool Check(string id)
{
if(GetFromWeakReference(id) != null)
@@ -1578,6 +1620,11 @@ namespace OpenSim.Region.CoreModules.Asset
return true;
}
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ return;
+ }
+
public bool[] AssetsExist(string[] ids)
{
bool[] exist = new bool[ids.Length];
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index eaba3e2ab3..b92fa63a5f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -267,6 +267,46 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
});
}
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ if (m_Cache != null)
+ {
+ AssetBase asset;
+ if (!m_Cache.GetFromMemory(id, out asset))
+ {
+ callBack(null);
+ return;
+ }
+
+ if (asset != null)
+ {
+ callBack(asset);
+ return;
+ }
+ }
+
+ if (id.Equals(Util.UUIDZeroString))
+ {
+ callBack(null);
+ return;
+ }
+
+ m_AssetService.Get(id, null, delegate (string assetID, object s, AssetBase a)
+ {
+ if (m_Cache != null)
+ {
+ if (a == null)
+ m_Cache.CacheNegative(assetID);
+ else
+ m_Cache.Cache(a);
+ }
+ //if (null == a)
+ //. m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not asynchronously find asset with id {0}", id);
+
+ Util.FireAndForget(o => callBack(a), null, "LocalAssetServiceConnector.GotFromServiceCallback");
+ });
+ }
+
public bool[] AssetsExist(string[] ids)
{
return m_AssetService.AssetsExist(ids);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RegionAssetConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RegionAssetConnectorModule.cs
index e58ae31bbd..b41ed78dd3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RegionAssetConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RegionAssetConnectorModule.cs
@@ -51,7 +51,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
{
private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType);
- private delegate void AssetRetrievedEx(AssetBase asset);
private bool m_Enabled = false;
private Scene m_aScene;
@@ -69,9 +68,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
//private int m_retryCounter;
//private bool m_inRetries;
- private Dictionary> m_AssetHandlers = new Dictionary>();
+ private Dictionary> m_AssetHandlers = new Dictionary>();
- private ObjectJobEngine m_requestQueue;
+ private ObjectJobEngine m_localRequestsQueue;
+ private ObjectJobEngine m_remoteRequestsQueue;
public Type ReplaceableInterface
{
@@ -135,7 +135,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
m_AssetPerms = new AssetPermissions(hgConfig);
}
- m_requestQueue = new ObjectJobEngine(AssetRequestProcessor, "GetAssetsWorkers", 2000, 2);
+ m_localRequestsQueue = new ObjectJobEngine(AssetRequestProcessor, "GetAssetsWorkers", 2000, 2);
+ m_remoteRequestsQueue = new ObjectJobEngine(AssetRequestProcessor, "GetRemoteAssetsWorkers", 2000, 2);
m_Enabled = true;
m_log.Info("[REGIONASSETCONNECTOR]: enabled");
}
@@ -151,8 +152,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
if (!m_Enabled)
return;
- m_requestQueue.Dispose();
- m_requestQueue = null;
+ m_localRequestsQueue.Dispose();
+ m_localRequestsQueue = null;
+ m_remoteRequestsQueue.Dispose();
+ m_remoteRequestsQueue = null;
+
+
}
public void AddRegion(Scene scene)
@@ -339,20 +344,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
AssetBase asset = null;
if (m_Cache != null)
{
- if (!m_Cache.Get(id, out asset))
+ if (!m_Cache.GetFromMemory(id, out asset))
+ {
+ callBack(id, sender, null);
return false;
+ }
}
if (asset == null)
{
if (id.Equals(Util.UUIDZeroString))
+ {
+ callBack(id, sender, null);
return false;
+ }
lock (m_AssetHandlers)
{
- AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate (AssetBase _asset) { callBack(id, sender, _asset); });
+ SimpleAssetRetrieved handlerEx = new SimpleAssetRetrieved(delegate (AssetBase _asset) { callBack(id, sender, _asset); _asset = null;});
- List handlers;
+ List handlers;
if (m_AssetHandlers.TryGetValue(id, out handlers))
{
// Someone else is already loading this asset. It will notify our handler when done.
@@ -360,11 +371,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
return true;
}
- handlers = new List();
+ handlers = new List();
handlers.Add(handlerEx);
m_AssetHandlers.Add(id, handlers);
- m_requestQueue.Enqueue(id);
+ m_localRequestsQueue.Enqueue(id);
}
}
else
@@ -376,16 +387,93 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
return true;
}
+ public struct ForeignAssetServiceGetData
+ {
+ public string id;
+ public string ForeignAssetService;
+ public bool StoreOnLocalGrid;
+ }
+
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ AssetBase asset = null;
+ if (m_Cache != null)
+ {
+ if (!m_Cache.GetFromMemory(id, out asset))
+ {
+ callBack(null);
+ return;
+ }
+ }
+
+ if (asset == null)
+ {
+ if (id.Equals(Util.UUIDZeroString))
+ {
+ callBack(null);
+ return;
+ }
+
+ lock (m_AssetHandlers)
+ {
+ SimpleAssetRetrieved handlerEx = new SimpleAssetRetrieved(delegate (AssetBase _asset) { callBack(_asset); _asset = null;});
+
+ List handlers;
+ if (m_AssetHandlers.TryGetValue(id, out handlers))
+ {
+ // Someone else is already loading this asset. It will notify our handler when done.
+ handlers.Add(handlerEx);
+ return;
+ }
+
+ handlers = new List();
+ handlers.Add(handlerEx);
+
+ m_AssetHandlers.Add(id, handlers);
+ if(string.IsNullOrEmpty(ForeignAssetService))
+ m_localRequestsQueue.Enqueue(id);
+ else
+ {
+ ForeignAssetServiceGetData fasgd = new ForeignAssetServiceGetData
+ {
+ id = id,
+ ForeignAssetService = ForeignAssetService,
+ StoreOnLocalGrid = StoreOnLocalGrid
+ };
+ m_remoteRequestsQueue.Enqueue(fasgd);
+ }
+ }
+ }
+ else
+ {
+ if (asset != null && (asset.Data == null || asset.Data.Length == 0))
+ asset = null;
+ callBack(asset);
+ }
+ }
+
private void AssetRequestProcessor(object o)
{
- string id = o as string;
- if(id == null)
+ if( o == null)
return;
try
{
- AssetBase a = Get(id);
- List handlers;
+ AssetBase a;
+ string id;
+ if (o is ForeignAssetServiceGetData)
+ {
+ var fasgd = (ForeignAssetServiceGetData)o;
+ id = fasgd.id;
+ a = Get(id, fasgd.ForeignAssetService, fasgd.StoreOnLocalGrid);
+ }
+ else
+ {
+ id = (string)o;
+ a = Get(id);
+ }
+
+ List handlers;
lock (m_AssetHandlers)
{
handlers = m_AssetHandlers[id];
@@ -396,7 +484,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
{
Util.FireAndForget(x =>
{
- foreach (AssetRetrievedEx h in handlers)
+ foreach (SimpleAssetRetrieved h in handlers)
{
try
{
@@ -405,6 +493,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
catch { }
}
handlers.Clear();
+ a = null;
});
}
}
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index ca2235aae8..ed6580ff64 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -206,5 +206,9 @@ namespace OpenSim.Services.AssetService
return m_Database.Delete(id);
}
+
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ }
}
}
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs
index 1a5bac5d07..2bb82e55f7 100644
--- a/OpenSim/Services/AssetService/XAssetService.cs
+++ b/OpenSim/Services/AssetService/XAssetService.cs
@@ -227,5 +227,10 @@ namespace OpenSim.Services.AssetService
Store(asset);
m_ChainedAssetService.Delete(asset.ID);
}
+
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ }
+
}
}
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
index 82898d07f1..d793c8d6a0 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
@@ -427,5 +427,10 @@ namespace OpenSim.Services.Connectors
string uri = m_ServerURI + "/assets/" + id;
return SynchronousRestObjectRequester.MakeRequest("DELETE", uri, 0, m_Auth);
}
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ return;
+ }
+
}
}
diff --git a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
index d4ff23d633..05dc57ed47 100644
--- a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
@@ -91,6 +91,7 @@ namespace OpenSim.Services.Connectors
return connector.Get(id);
}
+
public AssetBase GetCached(string id)
{
string url = string.Empty;
@@ -140,6 +141,11 @@ namespace OpenSim.Services.Connectors
return false;
}
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ return;
+ }
+
private struct AssetAndIndex
{
public UUID assetID;
diff --git a/OpenSim/Services/FSAssetService/FSAssetService.cs b/OpenSim/Services/FSAssetService/FSAssetService.cs
index 5acfeec3fb..bbee6ee148 100644
--- a/OpenSim/Services/FSAssetService/FSAssetService.cs
+++ b/OpenSim/Services/FSAssetService/FSAssetService.cs
@@ -834,5 +834,10 @@ namespace OpenSim.Services.FSAssetService
{
return Get(id);
}
+
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ return;
+ }
}
}
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs
index fd9d9d8825..041c8856a0 100755
--- a/OpenSim/Services/HypergridService/HGAssetService.cs
+++ b/OpenSim/Services/HypergridService/HGAssetService.cs
@@ -130,6 +130,11 @@ namespace OpenSim.Services.HypergridService
return null;
}
+ public void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack)
+ {
+ return;
+ }
+
public AssetMetadata GetMetadata(string id)
{
AssetMetadata meta = m_assetService.GetMetadata(id);
diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs
index 208a36c121..55c72c0f3e 100644
--- a/OpenSim/Services/Interfaces/IAssetService.cs
+++ b/OpenSim/Services/Interfaces/IAssetService.cs
@@ -30,7 +30,8 @@ using OpenSim.Framework;
namespace OpenSim.Services.Interfaces
{
- public delegate void AssetRetrieved(string id, Object sender, AssetBase asset);
+ public delegate void AssetRetrieved(string id, object sender, AssetBase asset);
+ public delegate void SimpleAssetRetrieved(AssetBase asset);
public interface IAssetService
{
@@ -76,6 +77,7 @@ namespace OpenSim.Services.Interfaces
///
/// True if the id was parseable, false otherwise
bool Get(string id, Object sender, AssetRetrieved handler);
+ void Get(string id, string ForeignAssetService, bool StoreOnLocalGrid, SimpleAssetRetrieved callBack);
///
/// Check if assets exist in the database.