diff options
23 files changed, 270 insertions, 61 deletions
diff --git a/OpenSim/Framework/IImprovedAssetCache.cs b/OpenSim/Framework/IAssetCache.cs index a853e90..8477116 100644 --- a/OpenSim/Framework/IImprovedAssetCache.cs +++ b/OpenSim/Framework/IAssetCache.cs | |||
@@ -29,7 +29,7 @@ using OpenSim.Framework; | |||
29 | 29 | ||
30 | namespace OpenSim.Framework | 30 | namespace OpenSim.Framework |
31 | { | 31 | { |
32 | public interface IImprovedAssetCache | 32 | public interface IAssetCache |
33 | { | 33 | { |
34 | /// <summary> | 34 | /// <summary> |
35 | /// Cache the specified asset. | 35 | /// Cache the specified asset. |
@@ -38,6 +38,12 @@ namespace OpenSim.Framework | |||
38 | void Cache(AssetBase asset); | 38 | void Cache(AssetBase asset); |
39 | 39 | ||
40 | /// <summary> | 40 | /// <summary> |
41 | /// Cache that the specified asset wasn't found. | ||
42 | /// </summary> | ||
43 | /// <param name='id'></param> | ||
44 | /// <summary> | ||
45 | void CacheNegative(string id); | ||
46 | |||
41 | /// Get an asset by its id. | 47 | /// Get an asset by its id. |
42 | /// </summary> | 48 | /// </summary> |
43 | /// <param name='id'></param> | 49 | /// <param name='id'></param> |
@@ -61,4 +67,4 @@ namespace OpenSim.Framework | |||
61 | /// </summary> | 67 | /// </summary> |
62 | void Clear(); | 68 | void Clear(); |
63 | } | 69 | } |
64 | } \ No newline at end of file | 70 | } |
diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index af28abc..966a6bc 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs | |||
@@ -50,7 +50,7 @@ namespace OpenSim.Framework | |||
50 | return retitems; | 50 | return retitems; |
51 | } | 51 | } |
52 | 52 | ||
53 | public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache) | 53 | public static WearableCacheItem[] FromOSD(OSD pInput, IAssetCache dataCache) |
54 | { | 54 | { |
55 | List<WearableCacheItem> ret = new List<WearableCacheItem>(); | 55 | List<WearableCacheItem> ret = new List<WearableCacheItem>(); |
56 | if (pInput.Type == OSDType.Array) | 56 | if (pInput.Type == OSDType.Array) |
@@ -100,7 +100,7 @@ namespace OpenSim.Framework | |||
100 | 100 | ||
101 | } | 101 | } |
102 | 102 | ||
103 | public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) | 103 | public static OSD ToOSD(WearableCacheItem[] pcacheItems, IAssetCache dataCache) |
104 | { | 104 | { |
105 | OSDArray arr = new OSDArray(); | 105 | OSDArray arr = new OSDArray(); |
106 | foreach (WearableCacheItem item in pcacheItems) | 106 | foreach (WearableCacheItem item in pcacheItems) |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 3cb999b..d9fdcde 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -206,6 +206,7 @@ namespace OpenSim | |||
206 | MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this)); | 206 | MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this)); |
207 | if (userStatsURI != String.Empty) | 207 | if (userStatsURI != String.Empty) |
208 | MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); | 208 | MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); |
209 | MainServer.Instance.AddStreamHandler(new OpenSim.SimRobotsHandler()); | ||
209 | 210 | ||
210 | if (managedStatsURI != String.Empty) | 211 | if (managedStatsURI != String.Empty) |
211 | { | 212 | { |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 90505e1..b8363ab 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -898,6 +898,26 @@ namespace OpenSim | |||
898 | } | 898 | } |
899 | } | 899 | } |
900 | 900 | ||
901 | /// <summary> | ||
902 | /// handler to supply serving http://domainname:port/robots.txt | ||
903 | /// </summary> | ||
904 | public class SimRobotsHandler : BaseStreamHandler | ||
905 | { | ||
906 | public SimRobotsHandler() : base("GET", "/robots.txt", "SimRobots.txt", "Simulator Robots.txt") {} | ||
907 | |||
908 | protected override byte[] ProcessRequest(string path, Stream request, | ||
909 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
910 | { | ||
911 | string robots = "# go away\nUser-agent: *\nDisallow: /\n"; | ||
912 | return Util.UTF8.GetBytes(robots); | ||
913 | } | ||
914 | |||
915 | public override string ContentType | ||
916 | { | ||
917 | get { return "text/plain"; } | ||
918 | } | ||
919 | } | ||
920 | |||
901 | #endregion | 921 | #endregion |
902 | 922 | ||
903 | /// <summary> | 923 | /// <summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a69b670..55050d9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -621,7 +621,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
621 | GroupsInView.Clear(); | 621 | GroupsInView.Clear(); |
622 | 622 | ||
623 | if(m_scene.GetNumberOfClients() == 0) | 623 | if(m_scene.GetNumberOfClients() == 0) |
624 | GC.Collect(); | 624 | { |
625 | GC.Collect(); | ||
626 | GC.WaitForPendingFinalizers(); | ||
627 | GC.Collect(); | ||
628 | } | ||
625 | } | 629 | } |
626 | 630 | ||
627 | public void Kick(string message) | 631 | public void Kick(string message) |
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 47dcbcd..6d1f0c2 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs | |||
@@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
57 | /// <summary>List of client methods to notify of results of decode</summary> | 57 | /// <summary>List of client methods to notify of results of decode</summary> |
58 | private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>(); | 58 | private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>(); |
59 | /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary> | 59 | /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary> |
60 | private IImprovedAssetCache m_cache; | 60 | private IAssetCache m_cache; |
61 | private IImprovedAssetCache Cache | 61 | private IAssetCache Cache |
62 | { | 62 | { |
63 | get | 63 | get |
64 | { | 64 | { |
65 | if (m_cache == null) | 65 | if (m_cache == null) |
66 | m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); | 66 | m_cache = m_scene.RequestModuleInterface<IAssetCache>(); |
67 | 67 | ||
68 | return m_cache; | 68 | return m_cache; |
69 | } | 69 | } |
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs index ebec9d2..14b0280 100644 --- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs | |||
@@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
91 | /// </code> | 91 | /// </code> |
92 | /// </example> | 92 | /// </example> |
93 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CenomeMemoryAssetCache")] | 93 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CenomeMemoryAssetCache")] |
94 | public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule | 94 | public class CenomeMemoryAssetCache : IAssetCache, ISharedRegionModule |
95 | { | 95 | { |
96 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 96 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
97 | 97 | ||
@@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
192 | expirationTime); | 192 | expirationTime); |
193 | } | 193 | } |
194 | 194 | ||
195 | #region IImprovedAssetCache Members | 195 | #region IAssetCache Members |
196 | 196 | ||
197 | public bool Check(string id) | 197 | public bool Check(string id) |
198 | { | 198 | { |
@@ -221,6 +221,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
221 | 221 | ||
222 | } | 222 | } |
223 | 223 | ||
224 | public void CacheNegative(string id) | ||
225 | { | ||
226 | // We don't do negative caching | ||
227 | } | ||
228 | |||
224 | /// <summary> | 229 | /// <summary> |
225 | /// Clear asset cache. | 230 | /// Clear asset cache. |
226 | /// </summary> | 231 | /// </summary> |
@@ -308,7 +313,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
308 | public void AddRegion(Scene scene) | 313 | public void AddRegion(Scene scene) |
309 | { | 314 | { |
310 | if (m_enabled) | 315 | if (m_enabled) |
311 | scene.RegisterModuleInterface<IImprovedAssetCache>(this); | 316 | scene.RegisterModuleInterface<IAssetCache>(this); |
312 | } | 317 | } |
313 | 318 | ||
314 | /// <summary> | 319 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index f720748..82bc5cc 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs | |||
@@ -40,7 +40,7 @@ using OpenSim.Services.Interfaces; | |||
40 | namespace OpenSim.Region.CoreModules.Asset | 40 | namespace OpenSim.Region.CoreModules.Asset |
41 | { | 41 | { |
42 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CoreAssetCache")] | 42 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CoreAssetCache")] |
43 | public class CoreAssetCache : ISharedRegionModule, IImprovedAssetCache | 43 | public class CoreAssetCache : ISharedRegionModule, IAssetCache |
44 | { | 44 | { |
45 | private static readonly ILog m_log = | 45 | private static readonly ILog m_log = |
46 | LogManager.GetLogger( | 46 | LogManager.GetLogger( |
@@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
98 | public void AddRegion(Scene scene) | 98 | public void AddRegion(Scene scene) |
99 | { | 99 | { |
100 | if (m_Enabled) | 100 | if (m_Enabled) |
101 | scene.RegisterModuleInterface<IImprovedAssetCache>(this); | 101 | scene.RegisterModuleInterface<IAssetCache>(this); |
102 | } | 102 | } |
103 | 103 | ||
104 | public void RemoveRegion(Scene scene) | 104 | public void RemoveRegion(Scene scene) |
@@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
110 | } | 110 | } |
111 | 111 | ||
112 | //////////////////////////////////////////////////////////// | 112 | //////////////////////////////////////////////////////////// |
113 | // IImprovedAssetCache | 113 | // IAssetCache |
114 | // | 114 | // |
115 | public bool Check(string id) | 115 | public bool Check(string id) |
116 | { | 116 | { |
@@ -124,6 +124,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
124 | m_Cache.Store(asset.ID, asset); | 124 | m_Cache.Store(asset.ID, asset); |
125 | } | 125 | } |
126 | 126 | ||
127 | public void CacheNegative(string id) | ||
128 | { | ||
129 | // We don't do negative caching | ||
130 | } | ||
131 | |||
127 | public AssetBase Get(string id) | 132 | public AssetBase Get(string id) |
128 | { | 133 | { |
129 | return (AssetBase)m_Cache.Get(id); | 134 | return (AssetBase)m_Cache.Get(id); |
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index b6dd565..84e13a0 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -55,7 +55,7 @@ using OpenSim.Services.Interfaces; | |||
55 | namespace OpenSim.Region.CoreModules.Asset | 55 | namespace OpenSim.Region.CoreModules.Asset |
56 | { | 56 | { |
57 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FlotsamAssetCache")] | 57 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FlotsamAssetCache")] |
58 | public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService | 58 | public class FlotsamAssetCache : ISharedRegionModule, IAssetCache, IAssetService |
59 | { | 59 | { |
60 | private static readonly ILog m_log = | 60 | private static readonly ILog m_log = |
61 | LogManager.GetLogger( | 61 | LogManager.GetLogger( |
@@ -78,6 +78,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
78 | private static ulong m_RequestsForInprogress; | 78 | private static ulong m_RequestsForInprogress; |
79 | private static ulong m_DiskHits; | 79 | private static ulong m_DiskHits; |
80 | private static ulong m_MemoryHits; | 80 | private static ulong m_MemoryHits; |
81 | private static ulong m_weakRefHits; | ||
81 | 82 | ||
82 | #if WAIT_ON_INPROGRESS_REQUESTS | 83 | #if WAIT_ON_INPROGRESS_REQUESTS |
83 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); | 84 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); |
@@ -91,9 +92,15 @@ namespace OpenSim.Region.CoreModules.Asset | |||
91 | private ExpiringCache<string, AssetBase> m_MemoryCache; | 92 | private ExpiringCache<string, AssetBase> m_MemoryCache; |
92 | private bool m_MemoryCacheEnabled = false; | 93 | private bool m_MemoryCacheEnabled = false; |
93 | 94 | ||
95 | private ExpiringCache<string, object> m_negativeCache; | ||
96 | private bool m_negativeCacheEnabled = true; | ||
97 | private bool m_negativeCacheSliding = false; | ||
98 | |||
94 | // Expiration is expressed in hours. | 99 | // Expiration is expressed in hours. |
95 | private double m_MemoryExpiration = 0.001; | 100 | private double m_MemoryExpiration = 0.016; |
96 | private const double m_DefaultFileExpiration = 48; | 101 | private const double m_DefaultFileExpiration = 48; |
102 | // Negative cache is in seconds | ||
103 | private int m_negativeExpiration = 120; | ||
97 | private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); | 104 | private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); |
98 | private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); | 105 | private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); |
99 | 106 | ||
@@ -107,6 +114,10 @@ namespace OpenSim.Region.CoreModules.Asset | |||
107 | private List<Scene> m_Scenes = new List<Scene>(); | 114 | private List<Scene> m_Scenes = new List<Scene>(); |
108 | private object timerLock = new object(); | 115 | private object timerLock = new object(); |
109 | 116 | ||
117 | private Dictionary<string,WeakReference> weakAssetReferences = new Dictionary<string, WeakReference>(); | ||
118 | private object weakAssetReferencesLock = new object(); | ||
119 | private bool m_updateFileTimeOnCacheHit = false; | ||
120 | |||
110 | public FlotsamAssetCache() | 121 | public FlotsamAssetCache() |
111 | { | 122 | { |
112 | m_InvalidChars.AddRange(Path.GetInvalidPathChars()); | 123 | m_InvalidChars.AddRange(Path.GetInvalidPathChars()); |
@@ -134,6 +145,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
134 | if (name == Name) | 145 | if (name == Name) |
135 | { | 146 | { |
136 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); | 147 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); |
148 | m_negativeCache = new ExpiringCache<string, object>(); | ||
137 | m_Enabled = true; | 149 | m_Enabled = true; |
138 | 150 | ||
139 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name); | 151 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name); |
@@ -152,6 +164,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
152 | m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); | 164 | m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); |
153 | m_MemoryExpiration = assetConfig.GetDouble("MemoryCacheTimeout", m_MemoryExpiration); | 165 | m_MemoryExpiration = assetConfig.GetDouble("MemoryCacheTimeout", m_MemoryExpiration); |
154 | m_MemoryExpiration *= 3600.0; // config in hours to seconds | 166 | m_MemoryExpiration *= 3600.0; // config in hours to seconds |
167 | |||
168 | m_negativeCacheEnabled = assetConfig.GetBoolean("NegativeCacheEnabled", m_negativeCacheEnabled); | ||
169 | m_negativeExpiration = assetConfig.GetInt("NegativeCacheTimeout", m_negativeExpiration); | ||
170 | m_negativeCacheSliding = assetConfig.GetBoolean("NegativeCacheSliding", m_negativeCacheSliding); | ||
171 | m_updateFileTimeOnCacheHit = assetConfig.GetBoolean("UpdateFileTimeOnCacheHit", m_updateFileTimeOnCacheHit); | ||
155 | 172 | ||
156 | #if WAIT_ON_INPROGRESS_REQUESTS | 173 | #if WAIT_ON_INPROGRESS_REQUESTS |
157 | m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); | 174 | m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); |
@@ -212,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
212 | { | 229 | { |
213 | if (m_Enabled) | 230 | if (m_Enabled) |
214 | { | 231 | { |
215 | scene.RegisterModuleInterface<IImprovedAssetCache>(this); | 232 | scene.RegisterModuleInterface<IAssetCache>(this); |
216 | m_Scenes.Add(scene); | 233 | m_Scenes.Add(scene); |
217 | } | 234 | } |
218 | } | 235 | } |
@@ -221,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
221 | { | 238 | { |
222 | if (m_Enabled) | 239 | if (m_Enabled) |
223 | { | 240 | { |
224 | scene.UnregisterModuleInterface<IImprovedAssetCache>(this); | 241 | scene.UnregisterModuleInterface<IAssetCache>(this); |
225 | m_Scenes.Remove(scene); | 242 | m_Scenes.Remove(scene); |
226 | lock(timerLock) | 243 | lock(timerLock) |
227 | { | 244 | { |
@@ -255,12 +272,23 @@ namespace OpenSim.Region.CoreModules.Asset | |||
255 | } | 272 | } |
256 | } | 273 | } |
257 | } | 274 | } |
275 | if (m_MemoryCacheEnabled) | ||
276 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); | ||
277 | |||
278 | lock(weakAssetReferencesLock) | ||
279 | weakAssetReferences = new Dictionary<string, WeakReference>(); | ||
258 | } | 280 | } |
259 | } | 281 | } |
260 | 282 | ||
261 | //////////////////////////////////////////////////////////// | 283 | //////////////////////////////////////////////////////////// |
262 | // IImprovedAssetCache | 284 | // IAssetCache |
263 | // | 285 | // |
286 | private void UpdateWeakReference(string key, AssetBase asset) | ||
287 | { | ||
288 | WeakReference aref = new WeakReference(asset); | ||
289 | lock(weakAssetReferencesLock) | ||
290 | weakAssetReferences[key] = aref; | ||
291 | } | ||
264 | 292 | ||
265 | private void UpdateMemoryCache(string key, AssetBase asset) | 293 | private void UpdateMemoryCache(string key, AssetBase asset) |
266 | { | 294 | { |
@@ -327,6 +355,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
327 | if (asset != null) | 355 | if (asset != null) |
328 | { | 356 | { |
329 | //m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); | 357 | //m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); |
358 | UpdateWeakReference(asset.ID, asset); | ||
330 | 359 | ||
331 | if (m_MemoryCacheEnabled) | 360 | if (m_MemoryCacheEnabled) |
332 | UpdateMemoryCache(asset.ID, asset); | 361 | UpdateMemoryCache(asset.ID, asset); |
@@ -336,6 +365,17 @@ namespace OpenSim.Region.CoreModules.Asset | |||
336 | } | 365 | } |
337 | } | 366 | } |
338 | 367 | ||
368 | public void CacheNegative(string id) | ||
369 | { | ||
370 | if (m_negativeCacheEnabled) | ||
371 | { | ||
372 | if (m_negativeCacheSliding) | ||
373 | m_negativeCache.AddOrUpdate(id, null, TimeSpan.FromSeconds(m_negativeExpiration)); | ||
374 | else | ||
375 | m_negativeCache.AddOrUpdate(id, null, m_negativeExpiration); | ||
376 | } | ||
377 | } | ||
378 | |||
339 | /// <summary> | 379 | /// <summary> |
340 | /// Updates the cached file with the current time. | 380 | /// Updates the cached file with the current time. |
341 | /// </summary> | 381 | /// </summary> |
@@ -354,6 +394,25 @@ namespace OpenSim.Region.CoreModules.Asset | |||
354 | } | 394 | } |
355 | } | 395 | } |
356 | 396 | ||
397 | private AssetBase GetFromWeakReference(string id) | ||
398 | { | ||
399 | AssetBase asset = null; | ||
400 | WeakReference aref; | ||
401 | |||
402 | lock(weakAssetReferencesLock) | ||
403 | { | ||
404 | if (weakAssetReferences.TryGetValue(id, out aref)) | ||
405 | { | ||
406 | asset = aref.Target as AssetBase; | ||
407 | if(asset == null) | ||
408 | weakAssetReferences.Remove(id); | ||
409 | else | ||
410 | m_weakRefHits++; | ||
411 | } | ||
412 | } | ||
413 | return asset; | ||
414 | } | ||
415 | |||
357 | /// <summary> | 416 | /// <summary> |
358 | /// Try to get an asset from the in-memory cache. | 417 | /// Try to get an asset from the in-memory cache. |
359 | /// </summary> | 418 | /// </summary> |
@@ -476,13 +535,38 @@ namespace OpenSim.Region.CoreModules.Asset | |||
476 | { | 535 | { |
477 | m_Requests++; | 536 | m_Requests++; |
478 | 537 | ||
538 | object dummy; | ||
539 | if (m_negativeCache.TryGetValue(id, out dummy)) | ||
540 | return null; | ||
541 | |||
479 | AssetBase asset = null; | 542 | AssetBase asset = null; |
543 | asset = GetFromWeakReference(id); | ||
544 | if (asset != null && m_updateFileTimeOnCacheHit) | ||
545 | { | ||
546 | string filename = GetFileName(id); | ||
547 | UpdateFileLastAccessTime(filename); | ||
548 | } | ||
480 | 549 | ||
481 | if (m_MemoryCacheEnabled) | 550 | if (m_MemoryCacheEnabled && asset == null) |
551 | { | ||
482 | asset = GetFromMemoryCache(id); | 552 | asset = GetFromMemoryCache(id); |
553 | if(asset != null) | ||
554 | { | ||
555 | UpdateWeakReference(id,asset); | ||
556 | if (m_updateFileTimeOnCacheHit) | ||
557 | { | ||
558 | string filename = GetFileName(id); | ||
559 | UpdateFileLastAccessTime(filename); | ||
560 | } | ||
561 | } | ||
562 | } | ||
483 | 563 | ||
484 | if (asset == null && m_FileCacheEnabled) | 564 | if (asset == null && m_FileCacheEnabled) |
565 | { | ||
485 | asset = GetFromFileCache(id); | 566 | asset = GetFromFileCache(id); |
567 | if(asset != null) | ||
568 | UpdateWeakReference(id,asset); | ||
569 | } | ||
486 | 570 | ||
487 | if (m_MemoryCacheEnabled && asset != null) | 571 | if (m_MemoryCacheEnabled && asset != null) |
488 | UpdateMemoryCache(id, asset); | 572 | UpdateMemoryCache(id, asset); |
@@ -494,6 +578,12 @@ namespace OpenSim.Region.CoreModules.Asset | |||
494 | GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); | 578 | GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); |
495 | } | 579 | } |
496 | 580 | ||
581 | if(asset == null) | ||
582 | { | ||
583 | |||
584 | |||
585 | } | ||
586 | |||
497 | return asset; | 587 | return asset; |
498 | } | 588 | } |
499 | 589 | ||
@@ -530,6 +620,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
530 | 620 | ||
531 | if (m_MemoryCacheEnabled) | 621 | if (m_MemoryCacheEnabled) |
532 | m_MemoryCache.Remove(id); | 622 | m_MemoryCache.Remove(id); |
623 | |||
624 | lock(weakAssetReferencesLock) | ||
625 | weakAssetReferences.Remove(id); | ||
533 | } | 626 | } |
534 | catch (Exception e) | 627 | catch (Exception e) |
535 | { | 628 | { |
@@ -553,7 +646,12 @@ namespace OpenSim.Region.CoreModules.Asset | |||
553 | } | 646 | } |
554 | 647 | ||
555 | if (m_MemoryCacheEnabled) | 648 | if (m_MemoryCacheEnabled) |
556 | m_MemoryCache.Clear(); | 649 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); |
650 | if (m_negativeCacheEnabled) | ||
651 | m_negativeCache = new ExpiringCache<string, object>(); | ||
652 | |||
653 | lock(weakAssetReferencesLock) | ||
654 | weakAssetReferences = new Dictionary<string, WeakReference>(); | ||
557 | } | 655 | } |
558 | 656 | ||
559 | private void CleanupExpiredFiles(object source, ElapsedEventArgs e) | 657 | private void CleanupExpiredFiles(object source, ElapsedEventArgs e) |
@@ -911,28 +1009,34 @@ namespace OpenSim.Region.CoreModules.Asset | |||
911 | List<string> outputLines = new List<string>(); | 1009 | List<string> outputLines = new List<string>(); |
912 | 1010 | ||
913 | double invReq = 100.0 / m_Requests; | 1011 | double invReq = 100.0 / m_Requests; |
1012 | |||
1013 | double weakHitRate = m_weakRefHits * invReq; | ||
1014 | int weakEntries = weakAssetReferences.Count; | ||
914 | 1015 | ||
915 | double fileHitRate = m_DiskHits * invReq; | 1016 | double fileHitRate = m_DiskHits * invReq; |
1017 | double TotalHitRate = weakHitRate + fileHitRate; | ||
1018 | |||
916 | outputLines.Add( | 1019 | outputLines.Add( |
917 | string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); | 1020 | string.Format("Total requests: {0}", m_Requests)); |
1021 | outputLines.Add( | ||
1022 | string.Format("unCollected Hit Rate: {0}% ({1} entries)", weakHitRate.ToString("0.00"),weakEntries)); | ||
1023 | outputLines.Add( | ||
1024 | string.Format("File Hit Rate: {0}%", fileHitRate.ToString("0.00"))); | ||
918 | 1025 | ||
919 | if (m_MemoryCacheEnabled) | 1026 | if (m_MemoryCacheEnabled) |
920 | { | 1027 | { |
921 | double HitRate = m_MemoryHits * invReq; | 1028 | double HitRate = m_MemoryHits * invReq; |
922 | |||
923 | outputLines.Add( | 1029 | outputLines.Add( |
924 | string.Format("Memory Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests)); | 1030 | string.Format("Memory Hit Rate: {0}%", HitRate.ToString("0.00"))); |
925 | 1031 | ||
926 | HitRate += fileHitRate; | 1032 | TotalHitRate += HitRate; |
927 | |||
928 | outputLines.Add( | ||
929 | string.Format("Total Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests)); | ||
930 | } | 1033 | } |
1034 | outputLines.Add( | ||
1035 | string.Format("Total Hit Rate: {0}%", TotalHitRate.ToString("0.00"))); | ||
931 | 1036 | ||
932 | outputLines.Add( | 1037 | outputLines.Add( |
933 | string.Format( | 1038 | string.Format( |
934 | "Unnecessary requests due to requests for assets that are currently downloading: {0}", | 1039 | "Requests overlap during file writing: {0}", m_RequestsForInprogress)); |
935 | m_RequestsForInprogress)); | ||
936 | 1040 | ||
937 | return outputLines; | 1041 | return outputLines; |
938 | } | 1042 | } |
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs index 5f76ac2..195bdaa 100644 --- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs | |||
@@ -41,7 +41,7 @@ using OpenSim.Services.Interfaces; | |||
41 | namespace OpenSim.Region.CoreModules.Asset | 41 | namespace OpenSim.Region.CoreModules.Asset |
42 | { | 42 | { |
43 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GlynnTuckerAssetCache")] | 43 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GlynnTuckerAssetCache")] |
44 | public class GlynnTuckerAssetCache : ISharedRegionModule, IImprovedAssetCache | 44 | public class GlynnTuckerAssetCache : ISharedRegionModule, IAssetCache |
45 | { | 45 | { |
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger( | 47 | LogManager.GetLogger( |
@@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
100 | public void AddRegion(Scene scene) | 100 | public void AddRegion(Scene scene) |
101 | { | 101 | { |
102 | if (m_Enabled) | 102 | if (m_Enabled) |
103 | scene.RegisterModuleInterface<IImprovedAssetCache>(this); | 103 | scene.RegisterModuleInterface<IAssetCache>(this); |
104 | } | 104 | } |
105 | 105 | ||
106 | public void RemoveRegion(Scene scene) | 106 | public void RemoveRegion(Scene scene) |
@@ -112,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
112 | } | 112 | } |
113 | 113 | ||
114 | //////////////////////////////////////////////////////////// | 114 | //////////////////////////////////////////////////////////// |
115 | // IImprovedAssetCache | 115 | // IAssetCache |
116 | // | 116 | // |
117 | 117 | ||
118 | public bool Check(string id) | 118 | public bool Check(string id) |
@@ -126,6 +126,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
126 | m_Cache.AddOrUpdate(asset.ID, asset); | 126 | m_Cache.AddOrUpdate(asset.ID, asset); |
127 | } | 127 | } |
128 | 128 | ||
129 | public void CacheNegative(string id) | ||
130 | { | ||
131 | // We don't do negative caching | ||
132 | } | ||
133 | |||
129 | public AssetBase Get(string id) | 134 | public AssetBase Get(string id) |
130 | { | 135 | { |
131 | Object asset = null; | 136 | Object asset = null; |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 41a3f52..67256ee 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -288,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
288 | if (bakedTextures.Count == 0) | 288 | if (bakedTextures.Count == 0) |
289 | return false; | 289 | return false; |
290 | 290 | ||
291 | IImprovedAssetCache cache = sp.Scene.RequestModuleInterface<IImprovedAssetCache>(); | 291 | IAssetCache cache = sp.Scene.RequestModuleInterface<IAssetCache>(); |
292 | if(cache == null) | 292 | if(cache == null) |
293 | return true; // no baked local caching so nothing to do | 293 | return true; // no baked local caching so nothing to do |
294 | 294 | ||
@@ -705,7 +705,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
705 | return 0; | 705 | return 0; |
706 | 706 | ||
707 | int texturesRebaked = 0; | 707 | int texturesRebaked = 0; |
708 | // IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); | 708 | // IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); |
709 | 709 | ||
710 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 710 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
711 | { | 711 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 3f7a8ee..df5265c 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | |||
@@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles | |||
69 | Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>(); | 69 | Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>(); |
70 | Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>(); | 70 | Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>(); |
71 | ExpiringCache<UUID, UserProfileCacheEntry> m_profilesCache = new ExpiringCache<UUID, UserProfileCacheEntry>(); | 71 | ExpiringCache<UUID, UserProfileCacheEntry> m_profilesCache = new ExpiringCache<UUID, UserProfileCacheEntry>(); |
72 | IImprovedAssetCache m_assetCache; | 72 | IAssetCache m_assetCache; |
73 | 73 | ||
74 | private JsonRpcRequestManager rpc = new JsonRpcRequestManager(); | 74 | private JsonRpcRequestManager rpc = new JsonRpcRequestManager(); |
75 | private bool m_allowUserProfileWebURLs = true; | 75 | private bool m_allowUserProfileWebURLs = true; |
@@ -221,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles | |||
221 | { | 221 | { |
222 | if(!Enabled) | 222 | if(!Enabled) |
223 | return; | 223 | return; |
224 | m_assetCache = Scene.RequestModuleInterface<IImprovedAssetCache>(); | 224 | m_assetCache = Scene.RequestModuleInterface<IAssetCache>(); |
225 | } | 225 | } |
226 | 226 | ||
227 | /// <summary> | 227 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 9eb41f9..31d1129 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs | |||
@@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
48 | LogManager.GetLogger( | 48 | LogManager.GetLogger( |
49 | MethodBase.GetCurrentMethod().DeclaringType); | 49 | MethodBase.GetCurrentMethod().DeclaringType); |
50 | 50 | ||
51 | private IImprovedAssetCache m_Cache = null; | 51 | private IAssetCache m_Cache = null; |
52 | private IAssetService m_GridService; | 52 | private IAssetService m_GridService; |
53 | private IAssetService m_HGService; | 53 | private IAssetService m_HGService; |
54 | 54 | ||
@@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
176 | 176 | ||
177 | if (m_Cache == null) | 177 | if (m_Cache == null) |
178 | { | 178 | { |
179 | m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | 179 | m_Cache = scene.RequestModuleInterface<IAssetCache>(); |
180 | 180 | ||
181 | if (!(m_Cache is ISharedRegionModule)) | 181 | if (!(m_Cache is ISharedRegionModule)) |
182 | m_Cache = null; | 182 | m_Cache = null; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 5f34450..d5d6667 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
44 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private IImprovedAssetCache m_Cache = null; | 47 | private IAssetCache m_Cache = null; |
48 | 48 | ||
49 | private IAssetService m_AssetService; | 49 | private IAssetService m_AssetService; |
50 | 50 | ||
@@ -128,7 +128,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
128 | 128 | ||
129 | if (m_Cache == null) | 129 | if (m_Cache == null) |
130 | { | 130 | { |
131 | m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | 131 | m_Cache = scene.RequestModuleInterface<IAssetCache>(); |
132 | 132 | ||
133 | if (!(m_Cache is ISharedRegionModule)) | 133 | if (!(m_Cache is ISharedRegionModule)) |
134 | m_Cache = null; | 134 | m_Cache = null; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs index e6eeacf..ff04f9d 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs | |||
@@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
48 | MethodBase.GetCurrentMethod().DeclaringType); | 48 | MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private bool m_Enabled = false; | 50 | private bool m_Enabled = false; |
51 | private IImprovedAssetCache m_Cache; | 51 | private IAssetCache m_Cache; |
52 | 52 | ||
53 | public Type ReplaceableInterface | 53 | public Type ReplaceableInterface |
54 | { | 54 | { |
@@ -111,7 +111,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
111 | 111 | ||
112 | if (m_Cache == null) | 112 | if (m_Cache == null) |
113 | { | 113 | { |
114 | m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | 114 | m_Cache = scene.RequestModuleInterface<IAssetCache>(); |
115 | 115 | ||
116 | // Since we are a shared module and scene data is not | 116 | // Since we are a shared module and scene data is not |
117 | // available for every method, the cache must be shared, too | 117 | // available for every method, the cache must be shared, too |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e44f11a..d7a4ca4 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1582,6 +1582,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | GC.Collect(); | 1584 | GC.Collect(); |
1585 | GC.WaitForPendingFinalizers(); | ||
1586 | GC.Collect(); | ||
1585 | // tell physics to finish building actor | 1587 | // tell physics to finish building actor |
1586 | m_sceneGraph.ProcessPhysicsPreSimulation(); | 1588 | m_sceneGraph.ProcessPhysicsPreSimulation(); |
1587 | 1589 | ||
@@ -1856,13 +1858,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1856 | 1858 | ||
1857 | if (!LoginsEnabled && Frame == 20) | 1859 | if (!LoginsEnabled && Frame == 20) |
1858 | { | 1860 | { |
1859 | // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); | ||
1860 | |||
1861 | // In 99.9% of cases it is a bad idea to manually force garbage collection. However, | ||
1862 | // this is a rare case where we know we have just went through a long cycle of heap | ||
1863 | // allocations, and there is no more work to be done until someone logs in | ||
1864 | GC.Collect(); | 1861 | GC.Collect(); |
1865 | 1862 | GC.WaitForPendingFinalizers(); | |
1863 | GC.Collect(); | ||
1866 | if (!LoginLock) | 1864 | if (!LoginLock) |
1867 | { | 1865 | { |
1868 | if (!StartDisabled) | 1866 | if (!StartDisabled) |
@@ -1887,6 +1885,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1887 | // LoginLock can currently only be set by a region module implementation. | 1885 | // LoginLock can currently only be set by a region module implementation. |
1888 | // If somehow this hasn't been done then the quickest way to bugfix is to see the | 1886 | // If somehow this hasn't been done then the quickest way to bugfix is to see the |
1889 | // NullReferenceException | 1887 | // NullReferenceException |
1888 | |||
1890 | IRegionReadyModule rrm = RequestModuleInterface<IRegionReadyModule>(); | 1889 | IRegionReadyModule rrm = RequestModuleInterface<IRegionReadyModule>(); |
1891 | rrm.TriggerRegionReady(this); | 1890 | rrm.TriggerRegionReady(this); |
1892 | } | 1891 | } |
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs index 7312bc3..b259f52 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs | |||
@@ -63,7 +63,7 @@ namespace OpenSim.Region.OptionalModules.Materials | |||
63 | 63 | ||
64 | public Type ReplaceableInterface { get { return null; } } | 64 | public Type ReplaceableInterface { get { return null; } } |
65 | 65 | ||
66 | IImprovedAssetCache m_cache; | 66 | IAssetCache m_cache; |
67 | private Scene m_scene = null; | 67 | private Scene m_scene = null; |
68 | private bool m_enabled = false; | 68 | private bool m_enabled = false; |
69 | private int m_maxMaterialsPerTransaction = 50; | 69 | private int m_maxMaterialsPerTransaction = 50; |
@@ -207,7 +207,7 @@ namespace OpenSim.Region.OptionalModules.Materials | |||
207 | { | 207 | { |
208 | if (!m_enabled) return; | 208 | if (!m_enabled) return; |
209 | 209 | ||
210 | m_cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | 210 | m_cache = scene.RequestModuleInterface<IAssetCache>(); |
211 | ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>(); | 211 | ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>(); |
212 | if (featuresModule != null) | 212 | if (featuresModule != null) |
213 | featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; | 213 | featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; |
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index 870c0bb..1725eb4 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | |||
@@ -214,6 +214,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
214 | m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; | 214 | m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; |
215 | m_scene.LoginLock = false; | 215 | m_scene.LoginLock = false; |
216 | 216 | ||
217 | GC.Collect(); | ||
218 | GC.WaitForPendingFinalizers(); | ||
219 | GC.Collect(); | ||
220 | |||
217 | if (!m_scene.StartDisabled) | 221 | if (!m_scene.StartDisabled) |
218 | { | 222 | { |
219 | m_scene.LoginsEnabled = true; | 223 | m_scene.LoginsEnabled = true; |
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index a6e8eb4..bdc3bef 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs | |||
@@ -49,7 +49,7 @@ namespace OpenSim.Services.Connectors | |||
49 | const int MAXSENDRETRIESLEN = 30; | 49 | const int MAXSENDRETRIESLEN = 30; |
50 | 50 | ||
51 | private string m_ServerURI = String.Empty; | 51 | private string m_ServerURI = String.Empty; |
52 | private IImprovedAssetCache m_Cache = null; | 52 | private IAssetCache m_Cache = null; |
53 | private int m_retryCounter; | 53 | private int m_retryCounter; |
54 | private bool m_inRetries; | 54 | private bool m_inRetries; |
55 | private List<AssetBase>[] m_sendRetries = new List<AssetBase>[MAXSENDRETRIESLEN]; | 55 | private List<AssetBase>[] m_sendRetries = new List<AssetBase>[MAXSENDRETRIESLEN]; |
@@ -233,7 +233,7 @@ namespace OpenSim.Services.Connectors | |||
233 | } | 233 | } |
234 | } | 234 | } |
235 | 235 | ||
236 | protected void SetCache(IImprovedAssetCache cache) | 236 | protected void SetCache(IAssetCache cache) |
237 | { | 237 | { |
238 | m_Cache = cache; | 238 | m_Cache = cache; |
239 | } | 239 | } |
@@ -260,8 +260,13 @@ namespace OpenSim.Services.Connectors | |||
260 | asset = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, m_Auth); | 260 | asset = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, m_Auth); |
261 | 261 | ||
262 | 262 | ||
263 | if (asset != null && m_Cache != null) | 263 | if (m_Cache != null) |
264 | m_Cache.Cache(asset); | 264 | { |
265 | if (asset != null) | ||
266 | m_Cache.Cache(asset); | ||
267 | else | ||
268 | m_Cache.CacheNegative(id); | ||
269 | } | ||
265 | } | 270 | } |
266 | return asset; | 271 | return asset; |
267 | } | 272 | } |
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs index d80e660..2ddd7a2 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs | |||
@@ -54,6 +54,8 @@ namespace OpenSim.Services.Connectors | |||
54 | 54 | ||
55 | private string m_ServerURI = String.Empty; | 55 | private string m_ServerURI = String.Empty; |
56 | 56 | ||
57 | private int m_maxRetries = 0; | ||
58 | |||
57 | /// <summary> | 59 | /// <summary> |
58 | /// Timeout for remote requests. | 60 | /// Timeout for remote requests. |
59 | /// </summary> | 61 | /// </summary> |
@@ -100,6 +102,7 @@ namespace OpenSim.Services.Connectors | |||
100 | m_ServerURI = serviceURI; | 102 | m_ServerURI = serviceURI; |
101 | 103 | ||
102 | m_requestTimeoutSecs = config.GetInt("RemoteRequestTimeout", m_requestTimeoutSecs); | 104 | m_requestTimeoutSecs = config.GetInt("RemoteRequestTimeout", m_requestTimeoutSecs); |
105 | m_maxRetries = config.GetInt("MaxRetries", m_maxRetries); | ||
103 | 106 | ||
104 | StatsManager.RegisterStat( | 107 | StatsManager.RegisterStat( |
105 | new Stat( | 108 | new Stat( |
@@ -700,10 +703,20 @@ namespace OpenSim.Services.Connectors | |||
700 | 703 | ||
701 | RequestsMade++; | 704 | RequestsMade++; |
702 | 705 | ||
703 | string reply | 706 | string reply = String.Empty; |
704 | = SynchronousRestFormsRequester.MakeRequest( | 707 | int retries = 0; |
708 | |||
709 | do | ||
710 | { | ||
711 | reply = SynchronousRestFormsRequester.MakeRequest( | ||
705 | "POST", m_ServerURI + "/xinventory", | 712 | "POST", m_ServerURI + "/xinventory", |
706 | ServerUtils.BuildQueryString(sendData), m_requestTimeoutSecs, m_Auth); | 713 | ServerUtils.BuildQueryString(sendData), m_requestTimeoutSecs, m_Auth); |
714 | |||
715 | if (reply != String.Empty) | ||
716 | break; | ||
717 | |||
718 | retries++; | ||
719 | } while (retries <= m_maxRetries); | ||
707 | 720 | ||
708 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( | 721 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( |
709 | reply); | 722 | reply); |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 9ad4a7a..531939f 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs | |||
@@ -55,7 +55,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
55 | private static string ZeroID = UUID.Zero.ToString(); | 55 | private static string ZeroID = UUID.Zero.ToString(); |
56 | 56 | ||
57 | private string m_serverUrl = String.Empty; | 57 | private string m_serverUrl = String.Empty; |
58 | private IImprovedAssetCache m_cache; | 58 | private IAssetCache m_cache; |
59 | private bool m_Enabled = false; | 59 | private bool m_Enabled = false; |
60 | 60 | ||
61 | #region ISharedRegionModule | 61 | #region ISharedRegionModule |
@@ -65,7 +65,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
65 | { | 65 | { |
66 | if (m_cache == null) | 66 | if (m_cache == null) |
67 | { | 67 | { |
68 | IImprovedAssetCache cache = scene.RequestModuleInterface<IImprovedAssetCache>(); | 68 | IAssetCache cache = scene.RequestModuleInterface<IAssetCache>(); |
69 | if (cache is ISharedRegionModule) | 69 | if (cache is ISharedRegionModule) |
70 | m_cache = cache; | 70 | m_cache = cache; |
71 | } | 71 | } |
diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example index c0d7430..2b5d37e 100644 --- a/bin/config-include/FlotsamCache.ini.example +++ b/bin/config-include/FlotsamCache.ini.example | |||
@@ -22,7 +22,44 @@ | |||
22 | ; Set to false for no memory cache | 22 | ; Set to false for no memory cache |
23 | ; assets can be requested several times in short periods | 23 | ; assets can be requested several times in short periods |
24 | ; so even a small memory cache is useful | 24 | ; so even a small memory cache is useful |
25 | MemoryCacheEnabled = true | 25 | MemoryCacheEnabled = false |
26 | |||
27 | ; If a memory cache hit happens, or the asset is still in memory | ||
28 | ; due to other causes, update the timestamp on the disk file anyway. | ||
29 | ; Don't turn this on unless you share your asset cache between simulators | ||
30 | ; AND use an external process, e.g. cron job, to clean it up. | ||
31 | UpdateFileTimeOnCacheHit = false | ||
32 | |||
33 | ; Enabling this will cache negative fetches. If an asset is negative-cached | ||
34 | ; it will not be re-requested from the asset server again for a while. | ||
35 | ; Generally, this is a good thing. | ||
36 | ; | ||
37 | ; Regular expiration settings (non-sliding) mean that the asset will be | ||
38 | ; retried after the time has expired. Sliding expiration means that | ||
39 | ; the time the negative cache will keep the asset is refreshed each | ||
40 | ; time a fetch is attempted. Use sliding expiration if you have rogue | ||
41 | ; scripts hammering the asset server with requests for nonexistent | ||
42 | ; assets. | ||
43 | ; | ||
44 | ; There are two cases where negative caching may cause issues: | ||
45 | ; | ||
46 | ; 1 - If an invalid asset is repeatedly requested by a script and that asset is | ||
47 | ; subsequently created, it will not be seen until fcache clear | ||
48 | ; is used. This is a very theoretical scenario since UUID collisions | ||
49 | ; are deemed to be not occuring in practice. | ||
50 | ; This can only become an issue with sliding expiration time. | ||
51 | ; | ||
52 | ; 2 - If the asset service is clustered, an asset may not have propagated | ||
53 | ; to all cluster members when it is first attempted to fetch it. | ||
54 | ; This may theoretically occur with networked vendor systems and | ||
55 | ; would lead to an asset not found message. However, after the | ||
56 | ; expiration time has elapsed, the asset will the be fetchable. | ||
57 | ; | ||
58 | ; The defaults below are suitable for all small to medium installations | ||
59 | ; including grids. | ||
60 | NegativeCacheEnabled = true | ||
61 | NegativeCacheTimeout = 120 | ||
62 | NegativeCacheSliding = false | ||
26 | 63 | ||
27 | ; Set to false for no file cache | 64 | ; Set to false for no file cache |
28 | FileCacheEnabled = true | 65 | FileCacheEnabled = true |
@@ -32,7 +69,7 @@ | |||
32 | ; this is good if memory is not a problem. | 69 | ; this is good if memory is not a problem. |
33 | ; if memory is a problem then a few seconds may actually save same. | 70 | ; if memory is a problem then a few seconds may actually save same. |
34 | ; see hit rates with console comand: fcache status | 71 | ; see hit rates with console comand: fcache status |
35 | MemoryCacheTimeout = .001 ; 3.6s ie around 4s (1s resolution) | 72 | MemoryCacheTimeout = .016 // one minute |
36 | 73 | ||
37 | ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes | 74 | ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes |
38 | ; Specify 0 if you do not want your disk cache to expire | 75 | ; Specify 0 if you do not want your disk cache to expire |
diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 0922cf5..10a5b47 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example | |||
@@ -85,6 +85,7 @@ | |||
85 | ; Change this to your grid-wide inventory server | 85 | ; Change this to your grid-wide inventory server |
86 | ; | 86 | ; |
87 | InventoryServerURI = "${Const|BaseURL}:${Const|PrivatePort}" | 87 | InventoryServerURI = "${Const|BaseURL}:${Const|PrivatePort}" |
88 | ;MaxRetries = 0 | ||
88 | 89 | ||
89 | [GridInfo] | 90 | [GridInfo] |
90 | ; | 91 | ; |