Add negative caching to flotsam cache. Prevents scripts from hammering the asset server
parent
ec4c258794
commit
07b48fd58c
|
@ -38,6 +38,12 @@ namespace OpenSim.Framework
|
|||
void Cache(AssetBase asset);
|
||||
|
||||
/// <summary>
|
||||
/// Cache that the specified asset wasn't found.
|
||||
/// </summary>
|
||||
/// <param name='id'></param>
|
||||
/// <summary>
|
||||
void CacheNegative(string id);
|
||||
|
||||
/// Get an asset by its id.
|
||||
/// </summary>
|
||||
/// <param name='id'></param>
|
||||
|
|
|
@ -221,6 +221,11 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
|
||||
}
|
||||
|
||||
public void CacheNegative(string id)
|
||||
{
|
||||
// We don't do negative caching
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear asset cache.
|
||||
/// </summary>
|
||||
|
|
|
@ -124,6 +124,11 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
m_Cache.Store(asset.ID, asset);
|
||||
}
|
||||
|
||||
public void CacheNegative(string id)
|
||||
{
|
||||
// We don't do negative caching
|
||||
}
|
||||
|
||||
public AssetBase Get(string id)
|
||||
{
|
||||
return (AssetBase)m_Cache.Get(id);
|
||||
|
|
|
@ -92,9 +92,15 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
private ExpiringCache<string, AssetBase> m_MemoryCache;
|
||||
private bool m_MemoryCacheEnabled = false;
|
||||
|
||||
private ExpiringCache<string, object> m_negativeCache;
|
||||
private bool m_negativeCacheEnabled = true;
|
||||
private bool m_negativeCacheSliding = false;
|
||||
|
||||
// Expiration is expressed in hours.
|
||||
private double m_MemoryExpiration = 0.016;
|
||||
private const double m_DefaultFileExpiration = 48;
|
||||
// Negative cache is in seconds
|
||||
private int m_negativeExpiration = 120;
|
||||
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
|
||||
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
|
||||
|
||||
|
@ -139,6 +145,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
if (name == Name)
|
||||
{
|
||||
m_MemoryCache = new ExpiringCache<string, AssetBase>();
|
||||
m_negativeCache = new ExpiringCache<string, object>();
|
||||
m_Enabled = true;
|
||||
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name);
|
||||
|
@ -158,6 +165,9 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
m_MemoryExpiration = assetConfig.GetDouble("MemoryCacheTimeout", m_MemoryExpiration);
|
||||
m_MemoryExpiration *= 3600.0; // config in hours to seconds
|
||||
|
||||
m_negativeCacheEnabled = assetConfig.GetBoolean("NegativeCacheEnabled", m_negativeCacheEnabled);
|
||||
m_negativeExpiration = assetConfig.GetInt("NegativeCacheTimeout", m_negativeExpiration);
|
||||
m_negativeCacheSliding = assetConfig.GetBoolean("NegativeCacheSliding", m_negativeCacheSliding);
|
||||
m_updateFileTimeOnCacheHit = assetConfig.GetBoolean("UpdateFileTimeOnCacheHit", m_updateFileTimeOnCacheHit);
|
||||
|
||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||
|
@ -355,6 +365,17 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
}
|
||||
}
|
||||
|
||||
public void CacheNegative(string id)
|
||||
{
|
||||
if (m_negativeCacheEnabled)
|
||||
{
|
||||
if (m_negativeCacheSliding)
|
||||
m_negativeCache.AddOrUpdate(id, null, TimeSpan.FromSeconds(m_negativeExpiration));
|
||||
else
|
||||
m_negativeCache.AddOrUpdate(id, null, m_negativeExpiration);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the cached file with the current time.
|
||||
/// </summary>
|
||||
|
@ -514,6 +535,10 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
{
|
||||
m_Requests++;
|
||||
|
||||
object dummy;
|
||||
if (m_negativeCache.TryGetValue(id, out dummy))
|
||||
return null;
|
||||
|
||||
AssetBase asset = null;
|
||||
asset = GetFromWeakReference(id);
|
||||
if (asset != null && m_updateFileTimeOnCacheHit)
|
||||
|
@ -622,6 +647,8 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
|
||||
if (m_MemoryCacheEnabled)
|
||||
m_MemoryCache = new ExpiringCache<string, AssetBase>();
|
||||
if (m_negativeCacheEnabled)
|
||||
m_negativeCache = new ExpiringCache<string, object>();
|
||||
|
||||
lock(weakAssetReferencesLock)
|
||||
weakAssetReferences = new Dictionary<string, WeakReference>();
|
||||
|
|
|
@ -126,6 +126,11 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
m_Cache.AddOrUpdate(asset.ID, asset);
|
||||
}
|
||||
|
||||
public void CacheNegative(string id)
|
||||
{
|
||||
// We don't do negative caching
|
||||
}
|
||||
|
||||
public AssetBase Get(string id)
|
||||
{
|
||||
Object asset = null;
|
||||
|
|
|
@ -260,8 +260,13 @@ namespace OpenSim.Services.Connectors
|
|||
asset = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, m_Auth);
|
||||
|
||||
|
||||
if (asset != null && m_Cache != null)
|
||||
m_Cache.Cache(asset);
|
||||
if (m_Cache != null)
|
||||
{
|
||||
if (asset != null)
|
||||
m_Cache.Cache(asset);
|
||||
else
|
||||
m_Cache.CacheNegative(id);
|
||||
}
|
||||
}
|
||||
return asset;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,43 @@
|
|||
; so even a small memory cache is useful
|
||||
MemoryCacheEnabled = false
|
||||
|
||||
; If a memory cache hit happens, or the asset is still in memory
|
||||
; due to other causes, update the timestamp on the disk file anyway.
|
||||
; Don't turn this on unless you share your asset cache between simulators
|
||||
; AND use an external process, e.g. cron job, to clean it up.
|
||||
UpdateFileTimeOnCacheHit = false
|
||||
|
||||
; Enabling this will cache negative fetches. If an asset is negative-cached
|
||||
; it will not be re-requested from the asset server again for a while.
|
||||
; Generally, this is a good thing.
|
||||
;
|
||||
; Regular expiration settings (non-sliding) mean that the asset will be
|
||||
; retried after the time has expired. Sliding expiration means that
|
||||
; the time the negative cache will keep the asset is refreshed each
|
||||
; time a fetch is attempted. Use sliding expiration if you have rogue
|
||||
; scripts hammering the asset server with requests for nonexistent
|
||||
; assets.
|
||||
;
|
||||
; There are two cases where negative caching may cause issues:
|
||||
;
|
||||
; 1 - If an invalid asset is repeatedly requested by a script and that asset is
|
||||
; subsequently created, it will not be seen until fcache clear
|
||||
; is used. This is a very theoretical scenario since UUID collisions
|
||||
; are deemed to be not occuring in practice.
|
||||
; This can only become an issue with sliding expiration time.
|
||||
;
|
||||
; 2 - If the asset service is clustered, an asset may not have propagated
|
||||
; to all cluster members when it is first attempted to fetch it.
|
||||
; This may theoretically occur with networked vendor systems and
|
||||
; would lead to an asset not found message. However, after the
|
||||
; expiration time has elapsed, the asset will the be fetchable.
|
||||
;
|
||||
; The defaults below are suitable for all small to medium installations
|
||||
; including grids.
|
||||
NegativeCacheEnabled = true
|
||||
NegativeCacheTimeout = 120
|
||||
NegativeCacheSliding = false
|
||||
|
||||
; Set to false for no file cache
|
||||
FileCacheEnabled = true
|
||||
|
||||
|
|
Loading…
Reference in New Issue