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_Lookup.Remove(uuid);
m_Index.Remove(item); 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); MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false; private bool m_Enabled = false;
private Cache m_Cache = new Cache(CacheMedium.Memory,
CacheStrategy.Aggressive,
CacheFlags.AllowUpdate);
public string Name public string Name
{ {
@ -69,6 +72,8 @@ namespace OpenSim.Region.CoreModules.Asset
m_Enabled = true; m_Enabled = true;
m_log.Info("[ASSET CACHE]: Core asset cache enabled"); 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) public void Cache(AssetBase asset)
{ {
m_Cache.Store(asset.ID, asset);
} }
public AssetBase Get(string id) public AssetBase Get(string id)
{ {
return null; return (AssetBase)m_Cache.Get(id);
} }
public void Expire(string id) public void Expire(string id)
{ {
m_Cache.Invalidate(id);
} }
public void Clear() public void Clear()
{ {
m_Cache.Clear();
} }
} }
} }

View File

@ -30,6 +30,7 @@ using Nini.Config;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using OpenSim.Framework;
using OpenSim.Servers.Base; using OpenSim.Servers.Base;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -37,14 +38,14 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
{ {
public class LocalAssetServicesConnector : ISharedRegionModule public class LocalAssetServicesConnector :
ISharedRegionModule, IAssetService
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<Scene, IImprovedAssetCache> m_AssetCache = private IImprovedAssetCache m_Cache = null;
new Dictionary<Scene, IImprovedAssetCache>();
private IAssetService m_AssetService; private IAssetService m_AssetService;
@ -108,15 +109,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
if (!m_Enabled) if (!m_Enabled)
return; return;
scene.RegisterModuleInterface<IAssetService>(m_AssetService); scene.RegisterModuleInterface<IAssetService>(this);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (!m_Enabled)
return;
m_AssetCache.Remove(scene);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -124,18 +121,113 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
if (!m_Enabled) if (!m_Enabled)
return; return;
m_AssetCache[scene] = if (m_Cache == null)
scene.RequestModuleInterface<IImprovedAssetCache>(); {
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_log.InfoFormat("[ASSET CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName);
m_AssetCache[scene] = if (m_Cache != null)
scene.RequestModuleInterface<IImprovedAssetCache>();
if (m_AssetCache[scene] != null)
{ {
m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); 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 bool m_Enabled = false;
private string m_ServerURI = String.Empty; private string m_ServerURI = String.Empty;
private Dictionary<Scene, IImprovedAssetCache> m_AssetCache = private IImprovedAssetCache m_Cache = null;
new Dictionary<Scene, IImprovedAssetCache>();
public string Name public string Name
{ {
@ -106,10 +105,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (!m_Enabled)
return;
m_AssetCache.Remove(scene);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -117,12 +112,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
if (!m_Enabled) if (!m_Enabled)
return; return;
m_AssetCache[scene] = if (m_Cache == null)
scene.RequestModuleInterface<IImprovedAssetCache>(); {
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); 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); 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; string uri = m_ServerURI + "/assets/" + id;
AssetBase asset = SynchronousRestObjectPoster. AssetBase asset = null;
BeginPostObject<int, AssetBase>("GET", uri, 0); 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; return asset;
} }
public AssetMetadata GetMetadata(string id) 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"; string uri = m_ServerURI + "/assets/" + id + "/metadata";
AssetMetadata asset = SynchronousRestObjectPoster. AssetMetadata asset = SynchronousRestObjectPoster.
@ -148,6 +169,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
public byte[] GetData(string id) 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); RestClient rc = new RestClient(m_ServerURI);
rc.AddResourcePath("assets"); rc.AddResourcePath("assets");
rc.AddResourcePath(id); rc.AddResourcePath(id);
@ -171,33 +200,70 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
return null; 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) public string Store(AssetBase asset)
{ {
string uri = m_ServerURI + "/assets/"; string uri = m_ServerURI + "/assets/";
string newID = SynchronousRestObjectPoster. string newID = SynchronousRestObjectPoster.
BeginPostObject<AssetBase, string>("POST", uri, asset); BeginPostObject<AssetBase, string>("POST", uri, asset);
if (newID != String.Empty)
{
if (m_Cache != null)
m_Cache.Cache(asset);
}
return newID; return newID;
} }
public bool UpdateContent(string id, byte[] data) public bool UpdateContent(string id, byte[] data)
{ {
AssetBase asset = new AssetBase(); AssetBase asset = null;
asset.ID = id;
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; asset.Data = data;
string uri = m_ServerURI + "/assets/" + id; string uri = m_ServerURI + "/assets/" + id;
return SynchronousRestObjectPoster. if (SynchronousRestObjectPoster.
BeginPostObject<AssetBase, bool>("POST", uri, asset); BeginPostObject<AssetBase, bool>("POST", uri, asset))
{
if (m_Cache != null)
m_Cache.Cache(asset);
return true;
}
return false;
} }
public bool Delete(string id) public bool Delete(string id)
{ {
string uri = m_ServerURI + "/assets/" + id; string uri = m_ServerURI + "/assets/" + id;
return SynchronousRestObjectPoster. if (SynchronousRestObjectPoster.
BeginPostObject<int, bool>("DELETE", uri, 0); BeginPostObject<int, bool>("DELETE", uri, 0))
{
if (m_Cache != null)
m_Cache.Expire(id);
return true;
}
return false; return false;
} }
} }

View File

@ -94,6 +94,20 @@ namespace OpenSim.Services.AssetService
return asset.Data; 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) public string Store(AssetBase asset)
{ {
m_Database.CreateAsset(asset); m_Database.CreateAsset(asset);

View File

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