mirror of
https://github.com/opensim/opensim.git
synced 2026-05-14 18:55:39 +08:00
some changes; let regions have own assets connector, make the services connector one be like ther older simpler one (as 0.8x). still not good
This commit is contained in:
@@ -562,6 +562,11 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Get(string id, out AssetBase asset)
|
||||
{
|
||||
asset = null;
|
||||
|
||||
@@ -33,7 +33,6 @@ using System.Reflection;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Connectors;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
@@ -41,12 +40,10 @@ using OpenSim.Services.Interfaces;
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGAssetBroker")]
|
||||
public class HGAssetBroker : AssetServicesConnector, ISharedRegionModule, IAssetService
|
||||
public class HGAssetBroker : RegionBaseAssetServicesConnector, ISharedRegionModule, IAssetService
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IAssetCache m_Cache = null;
|
||||
|
||||
private Scene m_aScene;
|
||||
|
||||
private bool m_Enabled = false;
|
||||
@@ -70,7 +67,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
Initialise(config);
|
||||
}
|
||||
|
||||
public override void Initialise(IConfigSource source)
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig moduleConfig = source.Configs["Modules"];
|
||||
if (moduleConfig != null)
|
||||
@@ -78,17 +75,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
string name = moduleConfig.GetString("AssetServices", "");
|
||||
if (name == Name)
|
||||
{
|
||||
IConfig assetConfig = source.Configs["AssetService"];
|
||||
if (assetConfig == null)
|
||||
{
|
||||
m_log.Error("[HG ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
|
||||
return;
|
||||
}
|
||||
|
||||
IConfig hgConfig = source.Configs["HGAssetService"];
|
||||
m_AssetPerms = new AssetPermissions(hgConfig); // it's ok if arg is null
|
||||
if(hgConfig != null)
|
||||
m_AssetPerms = new AssetPermissions(hgConfig); // it's ok if arg is null
|
||||
|
||||
base.Initialise(source);
|
||||
baseInitialise(source);
|
||||
m_Enabled = true;
|
||||
m_log.Info("[HG ASSET CONNECTOR]: HG asset broker enabled");
|
||||
}
|
||||
@@ -128,8 +119,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
|
||||
if (!(m_Cache is ISharedRegionModule))
|
||||
m_Cache = null;
|
||||
else
|
||||
SetCache(m_Cache);
|
||||
}
|
||||
|
||||
if (m_Cache != null)
|
||||
|
||||
@@ -131,19 +131,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
m_Cache = null;
|
||||
}
|
||||
|
||||
if (m_Cache != null)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset connector with caching for region {0}",
|
||||
if (m_Cache == null)
|
||||
m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset connector with caching for region {0}",
|
||||
scene.RegionInfo.RegionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Short-circuit directly to storage layer. This ends up storing temporary and local assets.
|
||||
//
|
||||
scene.UnregisterModuleInterface<IAssetService>(this);
|
||||
scene.RegisterModuleInterface<IAssetService>(m_AssetService);
|
||||
}
|
||||
m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset connector without caching for region {0}",
|
||||
scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
public AssetBase Get(string id)
|
||||
@@ -168,6 +161,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public AssetBase GetCached(string id)
|
||||
{
|
||||
// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Cache request for {0}", id);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,13 +40,11 @@ using OpenSim.Services.Interfaces;
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteAssetServicesConnector")]
|
||||
public class RemoteAssetServicesConnector : AssetServicesConnector, ISharedRegionModule, IAssetService
|
||||
public class RemoteAssetServicesConnector : RegionBaseAssetServicesConnector, ISharedRegionModule, IAssetService
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private IAssetCache m_Cache;
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
@@ -57,7 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
get { return "RemoteAssetServicesConnector"; }
|
||||
}
|
||||
|
||||
public override void Initialise(IConfigSource source)
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig moduleConfig = source.Configs["Modules"];
|
||||
if (moduleConfig != null)
|
||||
@@ -65,17 +63,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
string name = moduleConfig.GetString("AssetServices", "");
|
||||
if (name == Name)
|
||||
{
|
||||
IConfig assetConfig = source.Configs["AssetService"];
|
||||
if (assetConfig == null)
|
||||
{
|
||||
m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
|
||||
return;
|
||||
}
|
||||
|
||||
baseInitialise(source);
|
||||
m_Enabled = true;
|
||||
|
||||
base.Initialise(source);
|
||||
|
||||
m_log.Info("[ASSET CONNECTOR]: Remote assets enabled");
|
||||
}
|
||||
}
|
||||
@@ -115,17 +105,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
//
|
||||
if (!(m_Cache is ISharedRegionModule))
|
||||
m_Cache = null;
|
||||
else
|
||||
SetCache(m_Cache);
|
||||
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled remote assets for region {0}", scene.RegionInfo.RegionName);
|
||||
|
||||
if (m_Cache != null)
|
||||
{
|
||||
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName);
|
||||
}
|
||||
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled remote assets with caching for region {0}", scene.RegionInfo.RegionName);
|
||||
else
|
||||
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled remote assets without caching for region {0}", scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,11 @@ namespace OpenSim.Services.AssetService
|
||||
}
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual AssetBase GetCached(string id)
|
||||
{
|
||||
return Get(id);
|
||||
|
||||
@@ -129,6 +129,11 @@ namespace OpenSim.Services.AssetService
|
||||
}
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual AssetBase GetCached(string id)
|
||||
{
|
||||
return Get(id);
|
||||
|
||||
@@ -46,19 +46,10 @@ namespace OpenSim.Services.Connectors
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
const int MAXSENDRETRIESLEN = 30;
|
||||
protected IAssetCache m_Cache = null;
|
||||
public readonly object ConnectorLock = new object();
|
||||
|
||||
public object ConnectorLock = new object();
|
||||
|
||||
private string m_ServerURI = String.Empty;
|
||||
private IAssetCache m_Cache = null;
|
||||
private int m_retryCounter;
|
||||
private bool m_inRetries;
|
||||
private List<AssetBase>[] m_sendRetries = new List<AssetBase>[MAXSENDRETRIESLEN];
|
||||
private List<string>[] m_sendCachedRetries = new List<string>[MAXSENDRETRIESLEN];
|
||||
private System.Timers.Timer m_retryTimer;
|
||||
|
||||
private int m_maxAssetRequestConcurrency = 8;
|
||||
private string m_ServerURI = string.Empty;
|
||||
|
||||
private delegate void AssetRetrievedEx(AssetBase asset);
|
||||
|
||||
@@ -67,16 +58,6 @@ namespace OpenSim.Services.Connectors
|
||||
|
||||
private Dictionary<string, List<AssetRetrievedEx>> m_AssetHandlers = new Dictionary<string, List<AssetRetrievedEx>>();
|
||||
|
||||
private Dictionary<string, string> m_UriMap;
|
||||
|
||||
private Thread[] m_fetchThreads;
|
||||
|
||||
public int MaxAssetRequestConcurrency
|
||||
{
|
||||
get { return m_maxAssetRequestConcurrency; }
|
||||
set { m_maxAssetRequestConcurrency = value; }
|
||||
}
|
||||
|
||||
public AssetServicesConnector()
|
||||
{
|
||||
}
|
||||
@@ -94,8 +75,6 @@ namespace OpenSim.Services.Connectors
|
||||
public virtual void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig netconfig = source.Configs["Network"];
|
||||
if (netconfig != null)
|
||||
m_maxAssetRequestConcurrency = netconfig.GetInt("MaxRequestConcurrency",m_maxAssetRequestConcurrency);
|
||||
|
||||
IConfig assetConfig = source.Configs["AssetService"];
|
||||
if (assetConfig == null)
|
||||
@@ -107,8 +86,8 @@ namespace OpenSim.Services.Connectors
|
||||
m_ServerURI = assetConfig.GetString("AssetServerURI", string.Empty);
|
||||
if (string.IsNullOrEmpty(m_ServerURI))
|
||||
{
|
||||
IConfig netConfig = source.Configs["Network"];
|
||||
m_ServerURI = netConfig.GetString("asset_server_url", string.Empty);
|
||||
if(netconfig != null)
|
||||
m_ServerURI = netconfig.GetString("asset_server_url", string.Empty);
|
||||
}
|
||||
if (string.IsNullOrEmpty(m_ServerURI))
|
||||
{
|
||||
@@ -124,173 +103,17 @@ namespace OpenSim.Services.Connectors
|
||||
}
|
||||
|
||||
m_ServerURI = m_GridAssetsURL.URI;
|
||||
bool usemaps = assetConfig.GetBoolean("AssetServerIsCluster", false);
|
||||
|
||||
if(usemaps)
|
||||
{
|
||||
m_UriMap = new Dictionary<string, string>();
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
string prefix = i.ToString("x2");
|
||||
string groupHost = assetConfig.GetString("AssetServerHost_" + prefix, string.Empty);
|
||||
if(string.IsNullOrEmpty(groupHost))
|
||||
m_UriMap[prefix] = m_ServerURI;
|
||||
else
|
||||
{
|
||||
OSHHTPHost other = new OSHHTPHost(groupHost, true);
|
||||
if(!other.IsResolvedHost)
|
||||
{
|
||||
m_log.Error("[ASSET CONNECTOR]: Could not parse or resolve AssetServerHost_" + prefix);
|
||||
throw new Exception("Asset connector init error");
|
||||
}
|
||||
m_UriMap[prefix] = other.URI;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_UriMap = null;
|
||||
|
||||
m_retryTimer = new System.Timers.Timer();
|
||||
m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck);
|
||||
m_retryTimer.AutoReset = true;
|
||||
m_retryTimer.Interval = 60000;
|
||||
|
||||
m_fetchThreads = new Thread[3];
|
||||
|
||||
Initialise(source, "AssetService");
|
||||
|
||||
for (int i = 0 ; i < m_fetchThreads.Length; i++)
|
||||
{
|
||||
m_fetchThreads[i] = WorkManager.StartThread(AssetRequestProcessor, string.Format("GetAssetsWorker{0}", i));
|
||||
}
|
||||
}
|
||||
|
||||
private string MapServer(string id)
|
||||
private int m_maxAssetRequestConcurrency = 8;
|
||||
public int MaxAssetRequestConcurrency
|
||||
{
|
||||
if (m_UriMap == null)
|
||||
return m_ServerURI;
|
||||
|
||||
string prefix = id.Substring(0, 2).ToLower();
|
||||
|
||||
if (m_UriMap.TryGetValue(prefix, out string host))
|
||||
return host;
|
||||
|
||||
return m_UriMap["00"];
|
||||
get { return m_maxAssetRequestConcurrency; }
|
||||
set { m_maxAssetRequestConcurrency = value; }
|
||||
}
|
||||
|
||||
protected void retryCheck(object source, ElapsedEventArgs e)
|
||||
{
|
||||
lock(m_sendRetries)
|
||||
{
|
||||
if(m_inRetries)
|
||||
return;
|
||||
m_inRetries = true;
|
||||
}
|
||||
|
||||
m_retryCounter++;
|
||||
if(m_retryCounter >= 61 ) // avoid overflow 60 is max in use below
|
||||
m_retryCounter = 1;
|
||||
|
||||
int inUse = 0;
|
||||
int nextlevel;
|
||||
int timefactor;
|
||||
if(m_Cache == null)
|
||||
{
|
||||
List<AssetBase> retrylist;
|
||||
// we need to go down
|
||||
for(int i = MAXSENDRETRIESLEN - 1; i >= 0; i--)
|
||||
{
|
||||
lock(m_sendRetries)
|
||||
retrylist = m_sendRetries[i];
|
||||
|
||||
if(retrylist == null)
|
||||
continue;
|
||||
|
||||
inUse++;
|
||||
nextlevel = i + 1;
|
||||
|
||||
//We exponentially fall back on frequency until we reach one attempt per hour
|
||||
//The net result is that we end up in the queue for roughly 24 hours..
|
||||
//24 hours worth of assets could be a lot, so the hope is that the region admin
|
||||
//will have gotten the asset connector back online quickly!
|
||||
if(i == 0)
|
||||
timefactor = 1;
|
||||
else
|
||||
{
|
||||
timefactor = 1 << nextlevel;
|
||||
if (timefactor > 60)
|
||||
timefactor = 60;
|
||||
}
|
||||
|
||||
if(m_retryCounter < timefactor)
|
||||
continue; // to update inUse;
|
||||
|
||||
if (m_retryCounter % timefactor != 0)
|
||||
continue;
|
||||
|
||||
// a list to retry
|
||||
lock(m_sendRetries)
|
||||
m_sendRetries[i] = null;
|
||||
|
||||
// we are the only ones with a copy of this retrylist now
|
||||
foreach(AssetBase ass in retrylist)
|
||||
retryStore(ass, nextlevel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> retrylist;
|
||||
// we need to go down
|
||||
for (int i = MAXSENDRETRIESLEN - 1; i >= 0; i--)
|
||||
{
|
||||
lock (m_sendRetries)
|
||||
retrylist = m_sendCachedRetries[i];
|
||||
|
||||
if (retrylist == null)
|
||||
continue;
|
||||
|
||||
inUse++;
|
||||
nextlevel = i + 1;
|
||||
|
||||
//We exponentially fall back on frequency until we reach one attempt per hour
|
||||
//The net result is that we end up in the queue for roughly 24 hours..
|
||||
//24 hours worth of assets could be a lot, so the hope is that the region admin
|
||||
//will have gotten the asset connector back online quickly!
|
||||
if (i == 0)
|
||||
timefactor = 1;
|
||||
else
|
||||
{
|
||||
timefactor = 1 << nextlevel;
|
||||
if (timefactor > 60)
|
||||
timefactor = 60;
|
||||
}
|
||||
|
||||
if (m_retryCounter < timefactor)
|
||||
continue; // to update inUse;
|
||||
|
||||
if (m_retryCounter % timefactor != 0)
|
||||
continue;
|
||||
|
||||
// a list to retry
|
||||
lock (m_sendRetries)
|
||||
m_sendCachedRetries[i] = null;
|
||||
|
||||
// we are the only ones with a copy of this retrylist now
|
||||
foreach (string id in retrylist)
|
||||
retryCachedStore(id, nextlevel);
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_sendRetries)
|
||||
{
|
||||
if(inUse == 0 )
|
||||
m_retryTimer.Stop();
|
||||
|
||||
m_inRetries = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCache(IAssetCache cache)
|
||||
protected void SetCache(IAssetCache cache)
|
||||
{
|
||||
m_Cache = cache;
|
||||
}
|
||||
@@ -317,7 +140,7 @@ namespace OpenSim.Services.Connectors
|
||||
|
||||
if (asset == null || asset.Data == null || asset.Data.Length == 0)
|
||||
{
|
||||
string uri = MapServer(id) + "/assets/" + id;
|
||||
string uri = m_ServerURI + "/assets/" + id;
|
||||
|
||||
asset = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, m_Auth);
|
||||
if (m_Cache != null)
|
||||
@@ -331,34 +154,9 @@ namespace OpenSim.Services.Connectors
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetBase GetForeign(string id)
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
int type = Util.ParseForeignAssetID(id, out string uri, out string uuidstr);
|
||||
if (type < 0)
|
||||
return null;
|
||||
|
||||
AssetBase asset = null;
|
||||
if (m_Cache != null)
|
||||
{
|
||||
//if (!m_Cache.Get(uuidstr, out asset))
|
||||
// return null;
|
||||
m_Cache.Get(uuidstr, out asset); // negative cache is a fail on HG
|
||||
}
|
||||
|
||||
if (asset == null || asset.Data == null || asset.Data.Length == 0)
|
||||
{
|
||||
IServiceAuth auth = null;
|
||||
if (type == 0)
|
||||
{
|
||||
uri = MapServer(uuidstr) + "/assets/" + uuidstr;
|
||||
auth = m_Auth;
|
||||
}
|
||||
else
|
||||
uri = uri + "/assets/" + uuidstr;
|
||||
|
||||
asset = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, auth);
|
||||
}
|
||||
return asset;
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual AssetMetadata GetMetadata(string id)
|
||||
@@ -373,40 +171,12 @@ namespace OpenSim.Services.Connectors
|
||||
return fullAsset.Metadata;
|
||||
}
|
||||
|
||||
string uri = MapServer(id) + "/assets/" + id + "/metadata";
|
||||
string uri =m_ServerURI + "/assets/" + id + "/metadata";
|
||||
|
||||
AssetMetadata asset = SynchronousRestObjectRequester.MakeRequest<int, AssetMetadata>("GET", uri, 0, m_Auth);
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetMetadata GetForeignMetadata(string id)
|
||||
{
|
||||
int type = Util.ParseForeignAssetID(id, out string uri, out string uuidstr);
|
||||
if (type < 0)
|
||||
return null;
|
||||
|
||||
if (m_Cache != null)
|
||||
{
|
||||
AssetBase fullAsset;
|
||||
if (!m_Cache.Get(uuidstr, out fullAsset))
|
||||
return null;
|
||||
|
||||
if (fullAsset != null)
|
||||
return fullAsset.Metadata;
|
||||
}
|
||||
|
||||
IServiceAuth auth = null;
|
||||
if (type == 0)
|
||||
{
|
||||
auth = m_Auth;
|
||||
uri = MapServer(uuidstr) + "/assets/" + uuidstr + "/metadata";
|
||||
}
|
||||
else
|
||||
uri = uri + "/assets/" + uuidstr + "/metadata";
|
||||
|
||||
AssetMetadata asset = SynchronousRestObjectRequester.MakeRequest<int, AssetMetadata>("GET", uri, 0, auth);
|
||||
return asset;
|
||||
}
|
||||
|
||||
public virtual byte[] GetData(string id)
|
||||
{
|
||||
@@ -419,9 +189,7 @@ namespace OpenSim.Services.Connectors
|
||||
return fullAsset.Data;
|
||||
}
|
||||
|
||||
string uri = MapServer(id);
|
||||
|
||||
using (RestClient rc = new RestClient(uri))
|
||||
using (RestClient rc = new RestClient(m_ServerURI))
|
||||
{
|
||||
rc.AddResourcePath("assets/" + id + "/Data");
|
||||
rc.RequestMethod = "GET";
|
||||
@@ -435,49 +203,6 @@ namespace OpenSim.Services.Connectors
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetForeignData(string id)
|
||||
{
|
||||
int type = Util.ParseForeignAssetID(id, out string uri, out string uuidstr);
|
||||
if (type < 0)
|
||||
return null;
|
||||
|
||||
if (m_Cache != null)
|
||||
{
|
||||
if (!m_Cache.Get(uuidstr, out AssetBase fullAsset))
|
||||
return null;
|
||||
|
||||
if (fullAsset != null)
|
||||
return fullAsset.Data;
|
||||
}
|
||||
|
||||
IServiceAuth auth = null;
|
||||
if (type == 0)
|
||||
{
|
||||
uri = MapServer(uuidstr);
|
||||
auth = m_Auth;
|
||||
}
|
||||
|
||||
using (RestClient rc = new RestClient(uri))
|
||||
{
|
||||
rc.AddResourcePath("assets/" + id + "/Data");
|
||||
rc.RequestMethod = "GET";
|
||||
|
||||
using (MemoryStream s = rc.Request(auth))
|
||||
{
|
||||
if (s == null || s.Length == 0)
|
||||
return null;
|
||||
return s.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class QueuedAssetRequest
|
||||
{
|
||||
public string uri;
|
||||
public string id;
|
||||
public IServiceAuth auth;
|
||||
}
|
||||
|
||||
public virtual bool Get(string id, object sender, AssetRetrieved handler)
|
||||
{
|
||||
AssetBase asset = null;
|
||||
@@ -489,7 +214,7 @@ namespace OpenSim.Services.Connectors
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
string uri = MapServer(id) + "/assets/" + id;
|
||||
string uri = m_ServerURI + "/assets/" + id;
|
||||
|
||||
lock (m_AssetHandlers)
|
||||
{
|
||||
@@ -511,8 +236,10 @@ namespace OpenSim.Services.Connectors
|
||||
QueuedAssetRequest request = new QueuedAssetRequest();
|
||||
request.id = id;
|
||||
request.uri = uri;
|
||||
request.auth = m_Auth;
|
||||
m_requestQueue.Add(request);
|
||||
Util.FireAndForget(x =>
|
||||
{
|
||||
AssetRequestProcessor(request);
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -525,108 +252,40 @@ namespace OpenSim.Services.Connectors
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetForeign(string id, object sender, AssetRetrieved handler)
|
||||
private class QueuedAssetRequest
|
||||
{
|
||||
int type = Util.ParseForeignAssetID(id, out string uri, out string uuidstr);
|
||||
if (type < 0)
|
||||
return false;
|
||||
public string uri;
|
||||
public string id;
|
||||
}
|
||||
|
||||
AssetBase asset = null;
|
||||
if (m_Cache != null)
|
||||
private void AssetRequestProcessor(QueuedAssetRequest r)
|
||||
{
|
||||
string id = r.id;
|
||||
try
|
||||
{
|
||||
m_Cache.Get(uuidstr, out asset);
|
||||
}
|
||||
AssetBase a = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", r.uri, 0, 30000, m_Auth);
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
IServiceAuth auth = null;
|
||||
if (type == 0)
|
||||
{
|
||||
uri = MapServer(uuidstr) + "/assets/" + uuidstr;
|
||||
auth = m_Auth;
|
||||
}
|
||||
else
|
||||
uri = uri + "/assets/" + uuidstr;
|
||||
if (a != null && m_Cache != null)
|
||||
m_Cache.Cache(a);
|
||||
|
||||
List<AssetRetrievedEx> handlers;
|
||||
lock (m_AssetHandlers)
|
||||
{
|
||||
AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate (AssetBase _asset) { handler(id, sender, _asset); });
|
||||
|
||||
List<AssetRetrievedEx> 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 true;
|
||||
}
|
||||
|
||||
handlers = new List<AssetRetrievedEx>();
|
||||
handlers.Add(handlerEx);
|
||||
|
||||
m_AssetHandlers.Add(id, handlers);
|
||||
|
||||
QueuedAssetRequest request = new QueuedAssetRequest();
|
||||
request.id = id;
|
||||
request.uri = uri;
|
||||
request.auth = m_Auth;
|
||||
m_requestQueue.Add(request);
|
||||
handlers = m_AssetHandlers[id];
|
||||
m_AssetHandlers.Remove(id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (asset != null && (asset.Data == null || asset.Data.Length == 0))
|
||||
asset = null;
|
||||
handler(id, sender, asset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private BlockingCollection<QueuedAssetRequest> m_requestQueue = new BlockingCollection<QueuedAssetRequest>();
|
||||
private void AssetRequestProcessor()
|
||||
{
|
||||
QueuedAssetRequest r;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if(!m_requestQueue.TryTake(out r, 4500) || r == null)
|
||||
if(handlers != null)
|
||||
{
|
||||
Watchdog.UpdateThread();
|
||||
continue;
|
||||
}
|
||||
|
||||
Watchdog.UpdateThread();
|
||||
string id = r.id;
|
||||
|
||||
try
|
||||
{
|
||||
AssetBase a = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", r.uri, 0, 30000, r.auth);
|
||||
|
||||
if (a != null && m_Cache != null)
|
||||
m_Cache.Cache(a);
|
||||
|
||||
List<AssetRetrievedEx> handlers;
|
||||
lock (m_AssetHandlers)
|
||||
foreach (AssetRetrievedEx h in handlers)
|
||||
{
|
||||
handlers = m_AssetHandlers[id];
|
||||
m_AssetHandlers.Remove(id);
|
||||
}
|
||||
|
||||
if(handlers != null)
|
||||
{
|
||||
Util.FireAndForget(x =>
|
||||
{
|
||||
foreach (AssetRetrievedEx h in handlers)
|
||||
{
|
||||
try { h.Invoke(a); }
|
||||
catch { }
|
||||
}
|
||||
handlers.Clear();
|
||||
});
|
||||
try { h.Invoke(a); }
|
||||
catch { }
|
||||
}
|
||||
handlers.Clear();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public virtual bool[] AssetsExist(string[] ids)
|
||||
@@ -650,85 +309,6 @@ namespace OpenSim.Services.Connectors
|
||||
return exist;
|
||||
}
|
||||
|
||||
private struct AssetAndIndex
|
||||
{
|
||||
public string assetID;
|
||||
public int index;
|
||||
public IServiceAuth auth;
|
||||
|
||||
public AssetAndIndex(string assetID, int index, IServiceAuth auth)
|
||||
{
|
||||
this.assetID = assetID;
|
||||
this.index = index;
|
||||
this.auth = auth;
|
||||
}
|
||||
}
|
||||
|
||||
public bool[] ForeignAssetsExist(string[] ids)
|
||||
{
|
||||
bool[] exist = new bool[ids.Length];
|
||||
|
||||
var url2assets = new Dictionary<string, List<AssetAndIndex>>();
|
||||
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
int ltype = Util.ParseForeignAssetID(ids[i], out string lurl, out string luuidstr);
|
||||
if (ltype > 0)
|
||||
{
|
||||
IServiceAuth auth = null;
|
||||
|
||||
if (ltype == 0)
|
||||
{
|
||||
lurl = m_ServerURI;
|
||||
auth = m_Auth;
|
||||
}
|
||||
|
||||
List < AssetAndIndex > lst;
|
||||
if (!url2assets.TryGetValue(lurl, out lst))
|
||||
{
|
||||
lst = new List<AssetAndIndex>();
|
||||
url2assets.Add(lurl, lst);
|
||||
}
|
||||
lst.Add(new AssetAndIndex(luuidstr, i, auth));
|
||||
}
|
||||
}
|
||||
|
||||
// Query each of the servers in turn
|
||||
foreach (KeyValuePair<string, List<AssetAndIndex>> kvp in url2assets)
|
||||
{
|
||||
List<AssetAndIndex> curAssets = kvp.Value;
|
||||
string[] assetIDs = new string[curAssets.Count];
|
||||
IServiceAuth auth = curAssets[0].auth;
|
||||
for (int i = 0; i < assetIDs.Length;++i)
|
||||
assetIDs[i] = curAssets[i].assetID;
|
||||
|
||||
string uri = kvp.Key + "/get_assets_exist";
|
||||
|
||||
bool[] curExist = null;
|
||||
try
|
||||
{
|
||||
curExist = SynchronousRestObjectRequester.MakeRequest<string[], bool[]>("POST", uri, assetIDs, auth);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// This is most likely to happen because the server doesn't support this function,
|
||||
// so just silently return "doesn't exist" for all the assets.
|
||||
}
|
||||
|
||||
if(curExist != null)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (AssetAndIndex ai in curAssets)
|
||||
{
|
||||
exist[ai.index] = curExist[i];
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
string stringUUIDZero = UUID.Zero.ToString();
|
||||
|
||||
public virtual string Store(AssetBase asset)
|
||||
@@ -770,7 +350,7 @@ namespace OpenSim.Services.Connectors
|
||||
return asset.ID;
|
||||
}
|
||||
|
||||
string uri = MapServer(asset.FullID.ToString()) + "/assets/";
|
||||
string uri = m_ServerURI + "/assets/";
|
||||
|
||||
string newID = null;
|
||||
try
|
||||
@@ -784,26 +364,7 @@ namespace OpenSim.Services.Connectors
|
||||
|
||||
if (string.IsNullOrEmpty(newID) || newID == stringUUIDZero)
|
||||
{
|
||||
//The asset upload failed, try later
|
||||
lock(m_sendRetries)
|
||||
{
|
||||
if(m_Cache == null)
|
||||
{
|
||||
if (m_sendRetries[0] == null)
|
||||
m_sendRetries[0] = new List<AssetBase>();
|
||||
m_sendRetries[0].Add(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sendCachedRetries[0] == null)
|
||||
m_sendCachedRetries[0] = new List<string>();
|
||||
m_sendCachedRetries[0].Add(asset.ID);
|
||||
}
|
||||
|
||||
m_log.WarnFormat("[Assets] Upload failed: {0} type {1} will retry later",
|
||||
asset.ID.ToString(), asset.Type.ToString());
|
||||
m_retryTimer.Start();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -820,154 +381,6 @@ namespace OpenSim.Services.Connectors
|
||||
return asset.ID;
|
||||
}
|
||||
|
||||
public virtual string StoreForeign(AssetBase asset)
|
||||
{
|
||||
int type = Util.ParseForeignAssetID(asset.ID, out string uri, out string uuidstr);
|
||||
if(type < 0)
|
||||
return string.Empty;
|
||||
|
||||
if(type != 0)
|
||||
asset.ID = uuidstr;
|
||||
|
||||
if (m_Cache != null)
|
||||
m_Cache.Cache(asset);
|
||||
|
||||
if (asset.Temporary || asset.Local)
|
||||
{
|
||||
return asset.ID;
|
||||
}
|
||||
|
||||
IServiceAuth auth = null;
|
||||
if(type == 0)
|
||||
{
|
||||
uri = MapServer(uuidstr) + "/assets/";
|
||||
auth = m_Auth;
|
||||
}
|
||||
else
|
||||
uri += "/assets/";
|
||||
|
||||
string newID = null;
|
||||
try
|
||||
{
|
||||
newID = SynchronousRestObjectRequester.MakeRequest<AssetBase, string>("POST", uri, asset, 30000, auth);
|
||||
}
|
||||
catch
|
||||
{
|
||||
newID = null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newID) || newID == stringUUIDZero)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newID != asset.ID)
|
||||
{
|
||||
asset.ID = newID;
|
||||
if (m_Cache != null)
|
||||
m_Cache.Cache(asset);
|
||||
}
|
||||
}
|
||||
|
||||
return asset.ID;
|
||||
}
|
||||
|
||||
public void retryStore(AssetBase asset, int nextRetryLevel)
|
||||
{
|
||||
string uri = MapServer(asset.FullID.ToString()) + "/assets/";
|
||||
|
||||
string newID = null;
|
||||
try
|
||||
{
|
||||
newID = SynchronousRestObjectRequester.MakeRequest<AssetBase, string>("POST", uri, asset, 100000, m_Auth);
|
||||
}
|
||||
catch
|
||||
{
|
||||
newID = null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newID) || newID == stringUUIDZero)
|
||||
{
|
||||
if (nextRetryLevel >= MAXSENDRETRIESLEN)
|
||||
m_log.WarnFormat("[Assets] Giving up on uploading after {2} retries id: {0} type {1}",
|
||||
asset.ID.ToString(), asset.Type.ToString(), MAXSENDRETRIESLEN);
|
||||
else
|
||||
{
|
||||
lock (m_sendRetries)
|
||||
{
|
||||
if (m_sendRetries[nextRetryLevel] == null)
|
||||
m_sendRetries[nextRetryLevel] = new List<AssetBase>();
|
||||
|
||||
List<AssetBase> m_queue = m_sendRetries[nextRetryLevel];
|
||||
m_queue.Add(asset);
|
||||
m_log.WarnFormat("[Assets] Upload failed: {0} type {1} will retry later",
|
||||
asset.ID.ToString(), asset.Type.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), nextRetryLevel.ToString());
|
||||
if (newID != asset.ID)
|
||||
{
|
||||
asset.ID = newID;
|
||||
m_Cache?.Cache(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void retryCachedStore(string assetID, int nextRetryLevel)
|
||||
{
|
||||
m_Cache.Get(assetID,out AssetBase asset);
|
||||
if(asset == null)
|
||||
{
|
||||
m_log.WarnFormat("[Assets] asset not in cache on uploading after {2} retries id: {0}",
|
||||
assetID, MAXSENDRETRIESLEN);
|
||||
}
|
||||
|
||||
string uri = MapServer(asset.FullID.ToString()) + "/assets/";
|
||||
|
||||
string newID = null;
|
||||
try
|
||||
{
|
||||
newID = SynchronousRestObjectRequester.
|
||||
MakeRequest<AssetBase, string>("POST", uri, asset, 100000, m_Auth);
|
||||
}
|
||||
catch
|
||||
{
|
||||
newID = null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newID) || newID == stringUUIDZero)
|
||||
{
|
||||
if (nextRetryLevel >= MAXSENDRETRIESLEN)
|
||||
m_log.WarnFormat("[Assets] Giving up on uploading after {2} retries id: {0} type {1}",
|
||||
asset.ID.ToString(), asset.Type.ToString(), MAXSENDRETRIESLEN);
|
||||
else
|
||||
{
|
||||
lock (m_sendRetries)
|
||||
{
|
||||
if (m_sendCachedRetries[nextRetryLevel] == null)
|
||||
m_sendCachedRetries[nextRetryLevel] = new List<string>();
|
||||
|
||||
m_sendCachedRetries[nextRetryLevel].Add(assetID);
|
||||
m_log.WarnFormat("[Assets] Upload failed: {0} type {1} will retry later",
|
||||
asset.ID.ToString(), asset.Type.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), nextRetryLevel.ToString());
|
||||
if (newID != asset.ID)
|
||||
{
|
||||
asset.ID = newID;
|
||||
m_Cache?.Cache(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool UpdateContent(string id, byte[] data)
|
||||
{
|
||||
AssetBase asset = null;
|
||||
@@ -985,7 +398,7 @@ namespace OpenSim.Services.Connectors
|
||||
}
|
||||
asset.Data = data;
|
||||
|
||||
string uri = MapServer(id) + "/assets/" + id;
|
||||
string uri = m_ServerURI + "/assets/" + id;
|
||||
|
||||
if (SynchronousRestObjectRequester.MakeRequest<AssetBase, bool>("POST", uri, asset, m_Auth))
|
||||
{
|
||||
@@ -997,7 +410,7 @@ namespace OpenSim.Services.Connectors
|
||||
|
||||
public virtual bool Delete(string id)
|
||||
{
|
||||
string uri = MapServer(id) + "/assets/" + id;
|
||||
string uri = m_ServerURI + "/assets/" + id;
|
||||
|
||||
if (SynchronousRestObjectRequester.MakeRequest<int, bool>("DELETE", uri, 0, m_Auth))
|
||||
{
|
||||
|
||||
@@ -92,6 +92,12 @@ namespace OpenSim.Services.Connectors
|
||||
return null;
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
IAssetService connector = GetConnector(ForeignAssetService);
|
||||
return connector.Get(id);
|
||||
}
|
||||
|
||||
public AssetBase GetCached(string id)
|
||||
{
|
||||
string url = string.Empty;
|
||||
|
||||
@@ -420,6 +420,11 @@ namespace OpenSim.Services.FSAssetService
|
||||
return Get(id, out hash);
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private AssetBase Get(string id, out string sha)
|
||||
{
|
||||
string hash = string.Empty;
|
||||
|
||||
@@ -125,6 +125,11 @@ namespace OpenSim.Services.HypergridService
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public AssetMetadata GetMetadata(string id)
|
||||
{
|
||||
AssetMetadata meta = m_assetService.GetMetadata(id);
|
||||
|
||||
@@ -117,6 +117,11 @@ namespace OpenSim.Services.HypergridService
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetBase Get(string id, string ForeignAssetService)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public AssetMetadata GetMetadata(string id)
|
||||
{
|
||||
AssetMetadata meta = m_assetConnector.GetMetadata(id);
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace OpenSim.Services.Interfaces
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
AssetBase Get(string id);
|
||||
AssetBase Get(string id, string ForeignAssetService);
|
||||
|
||||
/// <summary>
|
||||
/// Get an asset's metadata
|
||||
|
||||
Reference in New Issue
Block a user