From 924d6e892a7b5a61e900b910a5a35de488963529 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 21:53:39 +0000 Subject: Make it possible to chain another asset service underneath the de-duplicating XAssetService. This makes it possible to use the dedupliicating service without needing to migrate all the existing asset data beforehand. Currently controlled by a ChainedServiceModule setting in [AssetService] (e.g. ChainedServiceModule = "OpenSim.Services.AssetService.dll:AssetService") Not yet ready for use. --- OpenSim/Services/AssetService/XAssetService.cs | 51 +++++++++++++++++----- OpenSim/Services/AssetService/XAssetServiceBase.cs | 47 +++++++++++++++----- 2 files changed, 75 insertions(+), 23 deletions(-) (limited to 'OpenSim/Services') diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs index a1d10ed..7dd48c9 100644 --- a/OpenSim/Services/AssetService/XAssetService.cs +++ b/OpenSim/Services/AssetService/XAssetService.cs @@ -39,8 +39,7 @@ using OpenMetaverse; namespace OpenSim.Services.AssetService { /// - /// This will be developed into a de-duplicating asset service. - /// XXX: Currently it's a just a copy of the existing AssetService. so please don't attempt to use it. + /// A de-duplicating asset service. /// public class XAssetService : XAssetServiceBase, IAssetService { @@ -48,7 +47,9 @@ namespace OpenSim.Services.AssetService protected static XAssetService m_RootInstance; - public XAssetService(IConfigSource config) : base(config) + public XAssetService(IConfigSource config) : this(config, "AssetService") {} + + public XAssetService(IConfigSource config, string configName) : base(config, configName) { if (m_RootInstance == null) { @@ -56,22 +57,21 @@ namespace OpenSim.Services.AssetService if (m_AssetLoader != null) { - IConfig assetConfig = config.Configs["AssetService"]; + IConfig assetConfig = config.Configs[configName]; if (assetConfig == null) throw new Exception("No AssetService configuration"); - string loaderArgs = assetConfig.GetString("AssetLoaderArgs", - String.Empty); + string loaderArgs = assetConfig.GetString("AssetLoaderArgs", String.Empty); bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true); - if (assetLoaderEnabled) + if (assetLoaderEnabled && !HasChainedAssetService) { m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs); m_AssetLoader.ForEachDefaultXmlAsset( loaderArgs, - delegate(AssetBase a) + a => { AssetBase existingAsset = Get(a.ID); // AssetMetadata existingMetadata = GetMetadata(a.ID); @@ -103,7 +103,14 @@ namespace OpenSim.Services.AssetService try { - return m_Database.GetAsset(assetID); + AssetBase asset = m_Database.GetAsset(assetID); + + if (asset != null) + return asset; + else if (HasChainedAssetService) + return m_ChainedAssetService.Get(id); + else + return null; } catch (Exception e) { @@ -128,9 +135,17 @@ namespace OpenSim.Services.AssetService AssetBase asset = m_Database.GetAsset(assetID); if (asset != null) + { return asset.Metadata; - - return null; + } + else if (HasChainedAssetService) + { + return m_ChainedAssetService.GetMetadata(id); + } + else + { + return null; + } } public virtual byte[] GetData(string id) @@ -143,7 +158,13 @@ namespace OpenSim.Services.AssetService return null; AssetBase asset = m_Database.GetAsset(assetID); - return asset.Data; + + if (asset != null) + return asset.Data; + else if (HasChainedAssetService) + return m_ChainedAssetService.GetData(id); + else + return null; } public virtual bool Get(string id, Object sender, AssetRetrieved handler) @@ -157,6 +178,9 @@ namespace OpenSim.Services.AssetService AssetBase asset = m_Database.GetAsset(assetID); + if (asset == null && HasChainedAssetService) + asset = m_ChainedAssetService.Get(id); + //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset); handler(id, sender, asset); @@ -194,6 +218,9 @@ namespace OpenSim.Services.AssetService if (!UUID.TryParse(id, out assetID)) return false; + // Don't bother deleting from a chained asset service. This isn't a big deal since deleting happens + // very rarely. + return m_Database.Delete(id); } } diff --git a/OpenSim/Services/AssetService/XAssetServiceBase.cs b/OpenSim/Services/AssetService/XAssetServiceBase.cs index 0c5c2c3..c118c9d 100644 --- a/OpenSim/Services/AssetService/XAssetServiceBase.cs +++ b/OpenSim/Services/AssetService/XAssetServiceBase.cs @@ -27,9 +27,11 @@ using System; using System.Reflection; +using log4net; using Nini.Config; using OpenSim.Framework; using OpenSim.Data; +using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenSim.Services.Base; @@ -37,10 +39,15 @@ namespace OpenSim.Services.AssetService { public class XAssetServiceBase : ServiceBase { - protected IXAssetDataPlugin m_Database = null; - protected IAssetLoader m_AssetLoader = null; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public XAssetServiceBase(IConfigSource config) : base(config) + protected IXAssetDataPlugin m_Database; + protected IAssetLoader m_AssetLoader; + protected IAssetService m_ChainedAssetService; + + protected bool HasChainedAssetService { get { return m_ChainedAssetService != null; } } + + public XAssetServiceBase(IConfigSource config, string configName) : base(config) { string dllName = String.Empty; string connString = String.Empty; @@ -48,7 +55,7 @@ namespace OpenSim.Services.AssetService // // Try reading the [AssetService] section first, if it exists // - IConfig assetConfig = config.Configs["AssetService"]; + IConfig assetConfig = config.Configs[configName]; if (assetConfig != null) { dllName = assetConfig.GetString("StorageProvider", dllName); @@ -77,17 +84,35 @@ namespace OpenSim.Services.AssetService if (m_Database == null) throw new Exception("Could not find a storage interface in the given module"); - m_Database.Initialise(connString); + string chainedAssetServiceDesignator = assetConfig.GetString("ChainedServiceModule", null); + + if (chainedAssetServiceDesignator != null) + { + m_log.InfoFormat( + "[XASSET SERVICE BASE]: Loading chained asset service from {0}", chainedAssetServiceDesignator); - string loaderName = assetConfig.GetString("DefaultAssetLoader", - String.Empty); + Object[] args = new Object[] { config, configName }; + m_ChainedAssetService = ServerUtils.LoadPlugin(chainedAssetServiceDesignator, args); - if (loaderName != String.Empty) + if (!HasChainedAssetService) + throw new Exception( + String.Format("Failed to load ChainedAssetService from {0}", chainedAssetServiceDesignator)); + } + + m_Database.Initialise(connString); + + if (HasChainedAssetService) { - m_AssetLoader = LoadPlugin(loaderName); + string loaderName = assetConfig.GetString("DefaultAssetLoader", + String.Empty); + + if (loaderName != String.Empty) + { + m_AssetLoader = LoadPlugin(loaderName); - if (m_AssetLoader == null) - throw new Exception("Asset loader could not be loaded"); + if (m_AssetLoader == null) + throw new Exception("Asset loader could not be loaded"); + } } } } -- cgit v1.1 From d05af4bdad7d4855b05eba909c5b21714e5f438a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 22:14:34 +0000 Subject: Fix bug in AssetService where requesting data only for an asset would throw an exception if the asset did not exist. --- OpenSim/Services/AssetService/AssetService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Services') diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index e7eb6fe..422fd0a 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -146,7 +146,11 @@ namespace OpenSim.Services.AssetService return null; AssetBase asset = m_Database.GetAsset(assetID); - return asset.Data; + + if (asset != null) + return asset.Data; + else + return null; } public virtual bool Get(string id, Object sender, AssetRetrieved handler) -- cgit v1.1 From bd0c1d9b6ac23b0fca8228fcf48da842b114773e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 22:33:39 +0000 Subject: Migrate assets from chained asset service to xassetservice as they are requested. This shrinks the asset database over time as duplicate assets are fetched. --- OpenSim/Services/AssetService/XAssetService.cs | 48 +++++++++++--------------- 1 file changed, 20 insertions(+), 28 deletions(-) (limited to 'OpenSim/Services') diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs index 7dd48c9..8a2ca7c 100644 --- a/OpenSim/Services/AssetService/XAssetService.cs +++ b/OpenSim/Services/AssetService/XAssetService.cs @@ -106,11 +106,20 @@ namespace OpenSim.Services.AssetService AssetBase asset = m_Database.GetAsset(assetID); if (asset != null) + { return asset; + } else if (HasChainedAssetService) - return m_ChainedAssetService.Get(id); - else - return null; + { + asset = m_ChainedAssetService.Get(id); + + if (asset != null) + MigrateFromChainedService(asset); + + return asset; + } + + return null; } catch (Exception e) { @@ -127,42 +136,23 @@ namespace OpenSim.Services.AssetService public virtual AssetMetadata GetMetadata(string id) { // m_log.DebugFormat("[XASSET SERVICE]: Get asset metadata for {0}", id); - - UUID assetID; - if (!UUID.TryParse(id, out assetID)) - return null; + AssetBase asset = Get(id); - AssetBase asset = m_Database.GetAsset(assetID); if (asset != null) - { return asset.Metadata; - } - else if (HasChainedAssetService) - { - return m_ChainedAssetService.GetMetadata(id); - } else - { return null; - } } public virtual byte[] GetData(string id) { // m_log.DebugFormat("[XASSET SERVICE]: Get asset data for {0}", id); - UUID assetID; - - if (!UUID.TryParse(id, out assetID)) - return null; - - AssetBase asset = m_Database.GetAsset(assetID); + AssetBase asset = Get(id); if (asset != null) return asset.Data; - else if (HasChainedAssetService) - return m_ChainedAssetService.GetData(id); else return null; } @@ -176,10 +166,7 @@ namespace OpenSim.Services.AssetService if (!UUID.TryParse(id, out assetID)) return false; - AssetBase asset = m_Database.GetAsset(assetID); - - if (asset == null && HasChainedAssetService) - asset = m_ChainedAssetService.Get(id); + AssetBase asset = Get(id); //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset); @@ -223,5 +210,10 @@ namespace OpenSim.Services.AssetService return m_Database.Delete(id); } + + private void MigrateFromChainedService(AssetBase asset) + { + Util.FireAndForget(o => { Store(asset); m_ChainedAssetService.Delete(asset.ID); }); + } } } \ No newline at end of file -- cgit v1.1 From 45dee383db016d1840c468b594db28ea714493a5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 22:42:34 +0000 Subject: refactor: Reuse Get() method in AssetService to eliminate some copy/paste in other Get methods --- OpenSim/Services/AssetService/AssetService.cs | 28 +++++---------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'OpenSim/Services') diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index 422fd0a..08fd3f8 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -123,29 +123,20 @@ namespace OpenSim.Services.AssetService public virtual AssetMetadata GetMetadata(string id) { // m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id); - - UUID assetID; - if (!UUID.TryParse(id, out assetID)) - return null; + AssetBase asset = Get(id); - AssetBase asset = m_Database.GetAsset(assetID); if (asset != null) return asset.Metadata; - - return null; + else + return null; } public virtual byte[] GetData(string id) { // m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id); - - UUID assetID; - if (!UUID.TryParse(id, out assetID)) - return null; - - AssetBase asset = m_Database.GetAsset(assetID); + AssetBase asset = Get(id); if (asset != null) return asset.Data; @@ -156,17 +147,8 @@ namespace OpenSim.Services.AssetService public virtual bool Get(string id, Object sender, AssetRetrieved handler) { //m_log.DebugFormat("[AssetService]: Get asset async {0}", id); - - UUID assetID; - if (!UUID.TryParse(id, out assetID)) - return false; - - AssetBase asset = m_Database.GetAsset(assetID); - - //m_log.DebugFormat("[AssetService]: Got asset {0}", asset); - - handler(id, sender, asset); + handler(id, sender, Get(id)); return true; } -- cgit v1.1