Connect up the new asset cache and introduce an asynchronous call path

for asset retrieval (full asset only) to ease migration to the new system
0.6.5-rc1
Melanie Thielker 2009-05-10 14:03:06 +00:00
parent d8e1842d25
commit 1a910b6e1d
6 changed files with 223 additions and 32 deletions

View File

@ -529,5 +529,11 @@ namespace OpenSim.Framework
m_Lookup.Remove(uuid);
m_Index.Remove(item);
}
public void Clear()
{
m_Index.Clear();
m_Lookup.Clear();
}
}
}

View File

@ -45,6 +45,9 @@ namespace OpenSim.Region.CoreModules.Asset
MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false;
private Cache m_Cache = new Cache(CacheMedium.Memory,
CacheStrategy.Aggressive,
CacheFlags.AllowUpdate);
public string Name
{
@ -69,6 +72,8 @@ namespace OpenSim.Region.CoreModules.Asset
m_Enabled = true;
m_log.Info("[ASSET CACHE]: Core asset cache enabled");
m_Cache.Size = 32768;
}
}
}
@ -99,19 +104,22 @@ namespace OpenSim.Region.CoreModules.Asset
public void Cache(AssetBase asset)
{
m_Cache.Store(asset.ID, asset);
}
public AssetBase Get(string id)
{
return null;
return (AssetBase)m_Cache.Get(id);
}
public void Expire(string id)
{
m_Cache.Invalidate(id);
}
public void Clear()
{
m_Cache.Clear();
}
}
}

View File

@ -30,6 +30,7 @@ using Nini.Config;
using System;
using System.Collections.Generic;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Servers.Base;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@ -37,14 +38,14 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
{
public class LocalAssetServicesConnector : ISharedRegionModule
public class LocalAssetServicesConnector :
ISharedRegionModule, IAssetService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<Scene, IImprovedAssetCache> m_AssetCache =
new Dictionary<Scene, IImprovedAssetCache>();
private IImprovedAssetCache m_Cache = null;
private IAssetService m_AssetService;
@ -108,15 +109,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
if (!m_Enabled)
return;
scene.RegisterModuleInterface<IAssetService>(m_AssetService);
scene.RegisterModuleInterface<IAssetService>(this);
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_AssetCache.Remove(scene);
}
public void RegionLoaded(Scene scene)
@ -124,18 +121,113 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
if (!m_Enabled)
return;
m_AssetCache[scene] =
scene.RequestModuleInterface<IImprovedAssetCache>();
if (m_Cache == null)
{
m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>();
if (!(m_Cache is ISharedRegionModule))
m_Cache = null;
}
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName);
m_AssetCache[scene] =
scene.RequestModuleInterface<IImprovedAssetCache>();
if (m_AssetCache[scene] != null)
if (m_Cache != null)
{
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName);
}
else
{
// Short-circuit directly to storage layer
//
scene.UnregisterModuleInterface<IAssetService>(this);
scene.RegisterModuleInterface<IAssetService>(m_AssetService);
}
}
public AssetBase Get(string id)
{
AssetBase asset = m_Cache.Get(id);
if (asset == null)
return m_AssetService.Get(id);
return asset;
}
public AssetMetadata GetMetadata(string id)
{
AssetBase asset = m_Cache.Get(id);
if (asset != null)
return asset.Metadata;
asset = m_AssetService.Get(id);
if (asset != null)
{
m_Cache.Cache(asset);
return asset.Metadata;
}
return null;
}
public byte[] GetData(string id)
{
AssetBase asset = m_Cache.Get(id);
if (asset != null)
return asset.Data;
asset = m_AssetService.Get(id);
if (asset != null)
{
m_Cache.Cache(asset);
return asset.Data;
}
return null;
}
public bool Get(string id, Object sender, AssetRetrieved handler)
{
AssetBase asset = m_Cache.Get(id);
if (asset != null)
{
handler(id, sender, asset);
return true;
}
return m_AssetService.Get(id, sender, delegate (string assetID, Object s, AssetBase a)
{
if (a != null)
m_Cache.Cache(a);
handler(assetID, s, a);
});
}
public string Store(AssetBase asset)
{
m_Cache.Cache(asset);
return m_AssetService.Store(asset);
}
public bool UpdateContent(string id, byte[] data)
{
AssetBase asset = m_Cache.Get(id);
if (asset != null)
{
asset.Data = data;
m_Cache.Cache(asset);
}
return m_AssetService.UpdateContent(id, data);
}
public bool Delete(string id)
{
m_Cache.Expire(id);
return m_AssetService.Delete(id);
}
}
}

View File

@ -49,8 +49,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
private bool m_Enabled = false;
private string m_ServerURI = String.Empty;
private Dictionary<Scene, IImprovedAssetCache> m_AssetCache =
new Dictionary<Scene, IImprovedAssetCache>();
private IImprovedAssetCache m_Cache = null;
public string Name
{
@ -106,10 +105,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_AssetCache.Remove(scene);
}
public void RegionLoaded(Scene scene)
@ -117,12 +112,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
if (!m_Enabled)
return;
m_AssetCache[scene] =
scene.RequestModuleInterface<IImprovedAssetCache>();
if (m_Cache == null)
{
m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>();
// Since we are a shared module and scene data is not
// available for every method, the cache must be shared, too
//
if (!(m_Cache is ISharedRegionModule))
m_Cache = null;
}
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled remote assets for region {0}", scene.RegionInfo.RegionName);
if (m_AssetCache[scene] != null)
if (m_Cache != null)
{
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName);
}
@ -132,13 +135,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
{
string uri = m_ServerURI + "/assets/" + id;
AssetBase asset = SynchronousRestObjectPoster.
BeginPostObject<int, AssetBase>("GET", uri, 0);
AssetBase asset = null;
if (m_Cache != null)
asset = m_Cache.Get(id);
if (asset == null)
{
asset = SynchronousRestObjectPoster.
BeginPostObject<int, AssetBase>("GET", uri, 0);
if (m_Cache != null)
m_Cache.Cache(asset);
}
return asset;
}
public AssetMetadata GetMetadata(string id)
{
if (m_Cache != null)
{
AssetBase fullAsset = m_Cache.Get(id);
if (fullAsset != null)
return fullAsset.Metadata;
}
string uri = m_ServerURI + "/assets/" + id + "/metadata";
AssetMetadata asset = SynchronousRestObjectPoster.
@ -148,6 +169,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
public byte[] GetData(string id)
{
if (m_Cache != null)
{
AssetBase fullAsset = m_Cache.Get(id);
if (fullAsset != null)
return fullAsset.Data;
}
RestClient rc = new RestClient(m_ServerURI);
rc.AddResourcePath("assets");
rc.AddResourcePath(id);
@ -171,33 +200,70 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
return null;
}
public bool Get(string id, Object sender, AssetRetrieved handler)
{
AssetBase asset = Get(id);
handler(id, sender, asset);
return true;
}
public string Store(AssetBase asset)
{
string uri = m_ServerURI + "/assets/";
string newID = SynchronousRestObjectPoster.
BeginPostObject<AssetBase, string>("POST", uri, asset);
if (newID != String.Empty)
{
if (m_Cache != null)
m_Cache.Cache(asset);
}
return newID;
}
public bool UpdateContent(string id, byte[] data)
{
AssetBase asset = new AssetBase();
asset.ID = id;
AssetBase asset = null;
if (m_Cache != null)
asset = m_Cache.Get(id);
if (asset == null)
{
AssetMetadata metadata = GetMetadata(id);
if (metadata == null)
return false;
asset = new AssetBase();
asset.Metadata = metadata;
}
asset.Data = data;
string uri = m_ServerURI + "/assets/" + id;
return SynchronousRestObjectPoster.
BeginPostObject<AssetBase, bool>("POST", uri, asset);
if (SynchronousRestObjectPoster.
BeginPostObject<AssetBase, bool>("POST", uri, asset))
{
if (m_Cache != null)
m_Cache.Cache(asset);
return true;
}
return false;
}
public bool Delete(string id)
{
string uri = m_ServerURI + "/assets/" + id;
return SynchronousRestObjectPoster.
BeginPostObject<int, bool>("DELETE", uri, 0);
if (SynchronousRestObjectPoster.
BeginPostObject<int, bool>("DELETE", uri, 0))
{
if (m_Cache != null)
m_Cache.Expire(id);
return true;
}
return false;
}
}

View File

@ -94,6 +94,20 @@ namespace OpenSim.Services.AssetService
return asset.Data;
}
public bool Get(string id, Object sender, AssetRetrieved handler)
{
UUID assetID;
if (!UUID.TryParse(id, out assetID))
return false;
AssetBase asset = m_Database.FetchAsset(assetID);
handler(id, sender, asset);
return true;
}
public string Store(AssetBase asset)
{
m_Database.CreateAsset(asset);

View File

@ -25,10 +25,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Framework;
namespace OpenSim.Services.Interfaces
{
public delegate void AssetRetrieved(string id, Object sender, AssetBase asset);
public interface IAssetService
{
// Three different ways to retrieve an asset
@ -37,6 +40,8 @@ namespace OpenSim.Services.Interfaces
AssetMetadata GetMetadata(string id);
byte[] GetData(string id);
bool Get(string id, Object sender, AssetRetrieved handler);
// Creates a new asset
// Returns a random ID if none is passed into it
//