diff options
author | Melanie Thielker | 2009-05-10 14:03:06 +0000 |
---|---|---|
committer | Melanie Thielker | 2009-05-10 14:03:06 +0000 |
commit | 1a910b6e1dbace70b27581c51148a8732b46de79 (patch) | |
tree | c13e58aa932b0db95ca895cd0ff1275c0014ca9f | |
parent | Add some asset cache plumbing. Change the generic cache from UUID to string (diff) | |
download | opensim-SC-1a910b6e1dbace70b27581c51148a8732b46de79.zip opensim-SC-1a910b6e1dbace70b27581c51148a8732b46de79.tar.gz opensim-SC-1a910b6e1dbace70b27581c51148a8732b46de79.tar.bz2 opensim-SC-1a910b6e1dbace70b27581c51148a8732b46de79.tar.xz |
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
6 files changed, 223 insertions, 32 deletions
diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs index 2d49146..79e20fc 100644 --- a/OpenSim/Framework/Cache.cs +++ b/OpenSim/Framework/Cache.cs | |||
@@ -529,5 +529,11 @@ namespace OpenSim.Framework | |||
529 | m_Lookup.Remove(uuid); | 529 | m_Lookup.Remove(uuid); |
530 | m_Index.Remove(item); | 530 | m_Index.Remove(item); |
531 | } | 531 | } |
532 | |||
533 | public void Clear() | ||
534 | { | ||
535 | m_Index.Clear(); | ||
536 | m_Lookup.Clear(); | ||
537 | } | ||
532 | } | 538 | } |
533 | } | 539 | } |
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index c4cc007..41d4bc6 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs | |||
@@ -45,6 +45,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
45 | MethodBase.GetCurrentMethod().DeclaringType); | 45 | MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private bool m_Enabled = false; | 47 | private bool m_Enabled = false; |
48 | private Cache m_Cache = new Cache(CacheMedium.Memory, | ||
49 | CacheStrategy.Aggressive, | ||
50 | CacheFlags.AllowUpdate); | ||
48 | 51 | ||
49 | public string Name | 52 | public string Name |
50 | { | 53 | { |
@@ -69,6 +72,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
69 | m_Enabled = true; | 72 | m_Enabled = true; |
70 | 73 | ||
71 | m_log.Info("[ASSET CACHE]: Core asset cache enabled"); | 74 | m_log.Info("[ASSET CACHE]: Core asset cache enabled"); |
75 | |||
76 | m_Cache.Size = 32768; | ||
72 | } | 77 | } |
73 | } | 78 | } |
74 | } | 79 | } |
@@ -99,19 +104,22 @@ namespace OpenSim.Region.CoreModules.Asset | |||
99 | 104 | ||
100 | public void Cache(AssetBase asset) | 105 | public void Cache(AssetBase asset) |
101 | { | 106 | { |
107 | m_Cache.Store(asset.ID, asset); | ||
102 | } | 108 | } |
103 | 109 | ||
104 | public AssetBase Get(string id) | 110 | public AssetBase Get(string id) |
105 | { | 111 | { |
106 | return null; | 112 | return (AssetBase)m_Cache.Get(id); |
107 | } | 113 | } |
108 | 114 | ||
109 | public void Expire(string id) | 115 | public void Expire(string id) |
110 | { | 116 | { |
117 | m_Cache.Invalidate(id); | ||
111 | } | 118 | } |
112 | 119 | ||
113 | public void Clear() | 120 | public void Clear() |
114 | { | 121 | { |
122 | m_Cache.Clear(); | ||
115 | } | 123 | } |
116 | } | 124 | } |
117 | } | 125 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs index 0a0f634..6f0a7f8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs | |||
@@ -30,6 +30,7 @@ using Nini.Config; | |||
30 | using System; | 30 | using System; |
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using OpenSim.Framework; | ||
33 | using OpenSim.Servers.Base; | 34 | using OpenSim.Servers.Base; |
34 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
35 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
@@ -37,14 +38,14 @@ using OpenSim.Services.Interfaces; | |||
37 | 38 | ||
38 | namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | 39 | namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset |
39 | { | 40 | { |
40 | public class LocalAssetServicesConnector : ISharedRegionModule | 41 | public class LocalAssetServicesConnector : |
42 | ISharedRegionModule, IAssetService | ||
41 | { | 43 | { |
42 | private static readonly ILog m_log = | 44 | private static readonly ILog m_log = |
43 | LogManager.GetLogger( | 45 | LogManager.GetLogger( |
44 | MethodBase.GetCurrentMethod().DeclaringType); | 46 | MethodBase.GetCurrentMethod().DeclaringType); |
45 | 47 | ||
46 | private Dictionary<Scene, IImprovedAssetCache> m_AssetCache = | 48 | private IImprovedAssetCache m_Cache = null; |
47 | new Dictionary<Scene, IImprovedAssetCache>(); | ||
48 | 49 | ||
49 | private IAssetService m_AssetService; | 50 | private IAssetService m_AssetService; |
50 | 51 | ||
@@ -108,15 +109,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
108 | if (!m_Enabled) | 109 | if (!m_Enabled) |
109 | return; | 110 | return; |
110 | 111 | ||
111 | scene.RegisterModuleInterface<IAssetService>(m_AssetService); | 112 | scene.RegisterModuleInterface<IAssetService>(this); |
112 | } | 113 | } |
113 | 114 | ||
114 | public void RemoveRegion(Scene scene) | 115 | public void RemoveRegion(Scene scene) |
115 | { | 116 | { |
116 | if (!m_Enabled) | ||
117 | return; | ||
118 | |||
119 | m_AssetCache.Remove(scene); | ||
120 | } | 117 | } |
121 | 118 | ||
122 | public void RegionLoaded(Scene scene) | 119 | public void RegionLoaded(Scene scene) |
@@ -124,18 +121,113 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
124 | if (!m_Enabled) | 121 | if (!m_Enabled) |
125 | return; | 122 | return; |
126 | 123 | ||
127 | m_AssetCache[scene] = | 124 | if (m_Cache == null) |
128 | scene.RequestModuleInterface<IImprovedAssetCache>(); | 125 | { |
126 | m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | ||
127 | |||
128 | if (!(m_Cache is ISharedRegionModule)) | ||
129 | m_Cache = null; | ||
130 | } | ||
129 | 131 | ||
130 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); | 132 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); |
131 | 133 | ||
132 | m_AssetCache[scene] = | 134 | if (m_Cache != null) |
133 | scene.RequestModuleInterface<IImprovedAssetCache>(); | ||
134 | |||
135 | if (m_AssetCache[scene] != null) | ||
136 | { | 135 | { |
137 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); | 136 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); |
138 | } | 137 | } |
138 | else | ||
139 | { | ||
140 | // Short-circuit directly to storage layer | ||
141 | // | ||
142 | scene.UnregisterModuleInterface<IAssetService>(this); | ||
143 | scene.RegisterModuleInterface<IAssetService>(m_AssetService); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | public AssetBase Get(string id) | ||
148 | { | ||
149 | AssetBase asset = m_Cache.Get(id); | ||
150 | |||
151 | if (asset == null) | ||
152 | return m_AssetService.Get(id); | ||
153 | return asset; | ||
154 | } | ||
155 | |||
156 | public AssetMetadata GetMetadata(string id) | ||
157 | { | ||
158 | AssetBase asset = m_Cache.Get(id); | ||
159 | |||
160 | if (asset != null) | ||
161 | return asset.Metadata; | ||
162 | |||
163 | asset = m_AssetService.Get(id); | ||
164 | if (asset != null) | ||
165 | { | ||
166 | m_Cache.Cache(asset); | ||
167 | return asset.Metadata; | ||
168 | } | ||
169 | |||
170 | return null; | ||
171 | } | ||
172 | |||
173 | public byte[] GetData(string id) | ||
174 | { | ||
175 | AssetBase asset = m_Cache.Get(id); | ||
176 | |||
177 | if (asset != null) | ||
178 | return asset.Data; | ||
179 | |||
180 | asset = m_AssetService.Get(id); | ||
181 | if (asset != null) | ||
182 | { | ||
183 | m_Cache.Cache(asset); | ||
184 | return asset.Data; | ||
185 | } | ||
186 | |||
187 | return null; | ||
188 | } | ||
189 | |||
190 | public bool Get(string id, Object sender, AssetRetrieved handler) | ||
191 | { | ||
192 | AssetBase asset = m_Cache.Get(id); | ||
193 | |||
194 | if (asset != null) | ||
195 | { | ||
196 | handler(id, sender, asset); | ||
197 | return true; | ||
198 | } | ||
199 | |||
200 | return m_AssetService.Get(id, sender, delegate (string assetID, Object s, AssetBase a) | ||
201 | { | ||
202 | if (a != null) | ||
203 | m_Cache.Cache(a); | ||
204 | handler(assetID, s, a); | ||
205 | }); | ||
206 | } | ||
207 | |||
208 | public string Store(AssetBase asset) | ||
209 | { | ||
210 | m_Cache.Cache(asset); | ||
211 | return m_AssetService.Store(asset); | ||
212 | } | ||
213 | |||
214 | public bool UpdateContent(string id, byte[] data) | ||
215 | { | ||
216 | AssetBase asset = m_Cache.Get(id); | ||
217 | if (asset != null) | ||
218 | { | ||
219 | asset.Data = data; | ||
220 | m_Cache.Cache(asset); | ||
221 | } | ||
222 | |||
223 | return m_AssetService.UpdateContent(id, data); | ||
224 | } | ||
225 | |||
226 | public bool Delete(string id) | ||
227 | { | ||
228 | m_Cache.Expire(id); | ||
229 | |||
230 | return m_AssetService.Delete(id); | ||
139 | } | 231 | } |
140 | } | 232 | } |
141 | } | 233 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/RemoteAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/RemoteAssetServiceConnector.cs index 835678d..667840f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/RemoteAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/RemoteAssetServiceConnector.cs | |||
@@ -49,8 +49,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
49 | 49 | ||
50 | private bool m_Enabled = false; | 50 | private bool m_Enabled = false; |
51 | private string m_ServerURI = String.Empty; | 51 | private string m_ServerURI = String.Empty; |
52 | private Dictionary<Scene, IImprovedAssetCache> m_AssetCache = | 52 | private IImprovedAssetCache m_Cache = null; |
53 | new Dictionary<Scene, IImprovedAssetCache>(); | ||
54 | 53 | ||
55 | public string Name | 54 | public string Name |
56 | { | 55 | { |
@@ -106,10 +105,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
106 | 105 | ||
107 | public void RemoveRegion(Scene scene) | 106 | public void RemoveRegion(Scene scene) |
108 | { | 107 | { |
109 | if (!m_Enabled) | ||
110 | return; | ||
111 | |||
112 | m_AssetCache.Remove(scene); | ||
113 | } | 108 | } |
114 | 109 | ||
115 | public void RegionLoaded(Scene scene) | 110 | public void RegionLoaded(Scene scene) |
@@ -117,12 +112,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
117 | if (!m_Enabled) | 112 | if (!m_Enabled) |
118 | return; | 113 | return; |
119 | 114 | ||
120 | m_AssetCache[scene] = | 115 | if (m_Cache == null) |
121 | scene.RequestModuleInterface<IImprovedAssetCache>(); | 116 | { |
117 | m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | ||
118 | |||
119 | // Since we are a shared module and scene data is not | ||
120 | // available for every method, the cache must be shared, too | ||
121 | // | ||
122 | if (!(m_Cache is ISharedRegionModule)) | ||
123 | m_Cache = null; | ||
124 | } | ||
122 | 125 | ||
123 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled remote assets for region {0}", scene.RegionInfo.RegionName); | 126 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled remote assets for region {0}", scene.RegionInfo.RegionName); |
124 | 127 | ||
125 | if (m_AssetCache[scene] != null) | 128 | if (m_Cache != null) |
126 | { | 129 | { |
127 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); | 130 | m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); |
128 | } | 131 | } |
@@ -132,13 +135,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
132 | { | 135 | { |
133 | string uri = m_ServerURI + "/assets/" + id; | 136 | string uri = m_ServerURI + "/assets/" + id; |
134 | 137 | ||
135 | AssetBase asset = SynchronousRestObjectPoster. | 138 | AssetBase asset = null; |
136 | BeginPostObject<int, AssetBase>("GET", uri, 0); | 139 | if (m_Cache != null) |
140 | asset = m_Cache.Get(id); | ||
141 | |||
142 | if (asset == null) | ||
143 | { | ||
144 | asset = SynchronousRestObjectPoster. | ||
145 | BeginPostObject<int, AssetBase>("GET", uri, 0); | ||
146 | |||
147 | if (m_Cache != null) | ||
148 | m_Cache.Cache(asset); | ||
149 | } | ||
137 | return asset; | 150 | return asset; |
138 | } | 151 | } |
139 | 152 | ||
140 | public AssetMetadata GetMetadata(string id) | 153 | public AssetMetadata GetMetadata(string id) |
141 | { | 154 | { |
155 | if (m_Cache != null) | ||
156 | { | ||
157 | AssetBase fullAsset = m_Cache.Get(id); | ||
158 | |||
159 | if (fullAsset != null) | ||
160 | return fullAsset.Metadata; | ||
161 | } | ||
162 | |||
142 | string uri = m_ServerURI + "/assets/" + id + "/metadata"; | 163 | string uri = m_ServerURI + "/assets/" + id + "/metadata"; |
143 | 164 | ||
144 | AssetMetadata asset = SynchronousRestObjectPoster. | 165 | AssetMetadata asset = SynchronousRestObjectPoster. |
@@ -148,6 +169,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
148 | 169 | ||
149 | public byte[] GetData(string id) | 170 | public byte[] GetData(string id) |
150 | { | 171 | { |
172 | if (m_Cache != null) | ||
173 | { | ||
174 | AssetBase fullAsset = m_Cache.Get(id); | ||
175 | |||
176 | if (fullAsset != null) | ||
177 | return fullAsset.Data; | ||
178 | } | ||
179 | |||
151 | RestClient rc = new RestClient(m_ServerURI); | 180 | RestClient rc = new RestClient(m_ServerURI); |
152 | rc.AddResourcePath("assets"); | 181 | rc.AddResourcePath("assets"); |
153 | rc.AddResourcePath(id); | 182 | rc.AddResourcePath(id); |
@@ -171,33 +200,70 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset | |||
171 | return null; | 200 | return null; |
172 | } | 201 | } |
173 | 202 | ||
203 | public bool Get(string id, Object sender, AssetRetrieved handler) | ||
204 | { | ||
205 | AssetBase asset = Get(id); | ||
206 | handler(id, sender, asset); | ||
207 | return true; | ||
208 | } | ||
174 | public string Store(AssetBase asset) | 209 | public string Store(AssetBase asset) |
175 | { | 210 | { |
176 | string uri = m_ServerURI + "/assets/"; | 211 | string uri = m_ServerURI + "/assets/"; |
177 | 212 | ||
178 | string newID = SynchronousRestObjectPoster. | 213 | string newID = SynchronousRestObjectPoster. |
179 | BeginPostObject<AssetBase, string>("POST", uri, asset); | 214 | BeginPostObject<AssetBase, string>("POST", uri, asset); |
215 | |||
216 | if (newID != String.Empty) | ||
217 | { | ||
218 | if (m_Cache != null) | ||
219 | m_Cache.Cache(asset); | ||
220 | } | ||
180 | return newID; | 221 | return newID; |
181 | } | 222 | } |
182 | 223 | ||
183 | public bool UpdateContent(string id, byte[] data) | 224 | public bool UpdateContent(string id, byte[] data) |
184 | { | 225 | { |
185 | AssetBase asset = new AssetBase(); | 226 | AssetBase asset = null; |
186 | asset.ID = id; | 227 | |
228 | if (m_Cache != null) | ||
229 | asset = m_Cache.Get(id); | ||
230 | |||
231 | if (asset == null) | ||
232 | { | ||
233 | AssetMetadata metadata = GetMetadata(id); | ||
234 | if (metadata == null) | ||
235 | return false; | ||
236 | |||
237 | asset = new AssetBase(); | ||
238 | asset.Metadata = metadata; | ||
239 | } | ||
187 | asset.Data = data; | 240 | asset.Data = data; |
188 | 241 | ||
189 | string uri = m_ServerURI + "/assets/" + id; | 242 | string uri = m_ServerURI + "/assets/" + id; |
190 | 243 | ||
191 | return SynchronousRestObjectPoster. | 244 | if (SynchronousRestObjectPoster. |
192 | BeginPostObject<AssetBase, bool>("POST", uri, asset); | 245 | BeginPostObject<AssetBase, bool>("POST", uri, asset)) |
246 | { | ||
247 | if (m_Cache != null) | ||
248 | m_Cache.Cache(asset); | ||
249 | |||
250 | return true; | ||
251 | } | ||
252 | return false; | ||
193 | } | 253 | } |
194 | 254 | ||
195 | public bool Delete(string id) | 255 | public bool Delete(string id) |
196 | { | 256 | { |
197 | string uri = m_ServerURI + "/assets/" + id; | 257 | string uri = m_ServerURI + "/assets/" + id; |
198 | 258 | ||
199 | return SynchronousRestObjectPoster. | 259 | if (SynchronousRestObjectPoster. |
200 | BeginPostObject<int, bool>("DELETE", uri, 0); | 260 | BeginPostObject<int, bool>("DELETE", uri, 0)) |
261 | { | ||
262 | if (m_Cache != null) | ||
263 | m_Cache.Expire(id); | ||
264 | |||
265 | return true; | ||
266 | } | ||
201 | return false; | 267 | return false; |
202 | } | 268 | } |
203 | } | 269 | } |
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index c279699..1e038d4 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs | |||
@@ -94,6 +94,20 @@ namespace OpenSim.Services.AssetService | |||
94 | return asset.Data; | 94 | return asset.Data; |
95 | } | 95 | } |
96 | 96 | ||
97 | public bool Get(string id, Object sender, AssetRetrieved handler) | ||
98 | { | ||
99 | UUID assetID; | ||
100 | |||
101 | if (!UUID.TryParse(id, out assetID)) | ||
102 | return false; | ||
103 | |||
104 | AssetBase asset = m_Database.FetchAsset(assetID); | ||
105 | |||
106 | handler(id, sender, asset); | ||
107 | |||
108 | return true; | ||
109 | } | ||
110 | |||
97 | public string Store(AssetBase asset) | 111 | public string Store(AssetBase asset) |
98 | { | 112 | { |
99 | m_Database.CreateAsset(asset); | 113 | m_Database.CreateAsset(asset); |
diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs index e1717d0..ec8a71b 100644 --- a/OpenSim/Services/Interfaces/IAssetService.cs +++ b/OpenSim/Services/Interfaces/IAssetService.cs | |||
@@ -25,10 +25,13 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | ||
28 | using OpenSim.Framework; | 29 | using OpenSim.Framework; |
29 | 30 | ||
30 | namespace OpenSim.Services.Interfaces | 31 | namespace OpenSim.Services.Interfaces |
31 | { | 32 | { |
33 | public delegate void AssetRetrieved(string id, Object sender, AssetBase asset); | ||
34 | |||
32 | public interface IAssetService | 35 | public interface IAssetService |
33 | { | 36 | { |
34 | // Three different ways to retrieve an asset | 37 | // Three different ways to retrieve an asset |
@@ -37,6 +40,8 @@ namespace OpenSim.Services.Interfaces | |||
37 | AssetMetadata GetMetadata(string id); | 40 | AssetMetadata GetMetadata(string id); |
38 | byte[] GetData(string id); | 41 | byte[] GetData(string id); |
39 | 42 | ||
43 | bool Get(string id, Object sender, AssetRetrieved handler); | ||
44 | |||
40 | // Creates a new asset | 45 | // Creates a new asset |
41 | // Returns a random ID if none is passed into it | 46 | // Returns a random ID if none is passed into it |
42 | // | 47 | // |