diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 75 | ||||
-rw-r--r-- | bin/config-include/FlotsamCache.ini.example | 13 |
2 files changed, 58 insertions, 30 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 9413598..b6dd565 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -62,7 +62,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
62 | MethodBase.GetCurrentMethod().DeclaringType); | 62 | MethodBase.GetCurrentMethod().DeclaringType); |
63 | 63 | ||
64 | private bool m_Enabled; | 64 | private bool m_Enabled; |
65 | private bool m_Running; | 65 | private bool m_timerRunning; |
66 | private bool m_cleanupRunning; | ||
66 | 67 | ||
67 | private const string m_ModuleName = "FlotsamAssetCache"; | 68 | private const string m_ModuleName = "FlotsamAssetCache"; |
68 | private const string m_DefaultCacheDirectory = "./assetcache"; | 69 | private const string m_DefaultCacheDirectory = "./assetcache"; |
@@ -91,9 +92,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
91 | private bool m_MemoryCacheEnabled = false; | 92 | private bool m_MemoryCacheEnabled = false; |
92 | 93 | ||
93 | // Expiration is expressed in hours. | 94 | // Expiration is expressed in hours. |
94 | private const double m_DefaultMemoryExpiration = 2; | 95 | private double m_MemoryExpiration = 0.001; |
95 | private const double m_DefaultFileExpiration = 48; | 96 | private const double m_DefaultFileExpiration = 48; |
96 | private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration); | ||
97 | private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); | 97 | private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); |
98 | private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); | 98 | private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); |
99 | 99 | ||
@@ -150,7 +150,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
150 | m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); | 150 | m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); |
151 | 151 | ||
152 | m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); | 152 | m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); |
153 | m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); | 153 | m_MemoryExpiration = assetConfig.GetDouble("MemoryCacheTimeout", m_MemoryExpiration); |
154 | m_MemoryExpiration *= 3600.0; // config in hours to seconds | ||
154 | 155 | ||
155 | #if WAIT_ON_INPROGRESS_REQUESTS | 156 | #if WAIT_ON_INPROGRESS_REQUESTS |
156 | m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); | 157 | m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); |
@@ -224,9 +225,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
224 | m_Scenes.Remove(scene); | 225 | m_Scenes.Remove(scene); |
225 | lock(timerLock) | 226 | lock(timerLock) |
226 | { | 227 | { |
227 | if(m_Running && m_Scenes.Count <= 0) | 228 | if(m_timerRunning && m_Scenes.Count <= 0) |
228 | { | 229 | { |
229 | m_Running = false; | 230 | m_timerRunning = false; |
230 | m_CacheCleanTimer.Stop(); | 231 | m_CacheCleanTimer.Stop(); |
231 | m_CacheCleanTimer.Close(); | 232 | m_CacheCleanTimer.Close(); |
232 | } | 233 | } |
@@ -242,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
242 | m_AssetService = scene.RequestModuleInterface<IAssetService>(); | 243 | m_AssetService = scene.RequestModuleInterface<IAssetService>(); |
243 | lock(timerLock) | 244 | lock(timerLock) |
244 | { | 245 | { |
245 | if(!m_Running) | 246 | if(!m_timerRunning) |
246 | { | 247 | { |
247 | if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) | 248 | if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) |
248 | { | 249 | { |
@@ -250,7 +251,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
250 | m_CacheCleanTimer.AutoReset = false; | 251 | m_CacheCleanTimer.AutoReset = false; |
251 | m_CacheCleanTimer.Elapsed += CleanupExpiredFiles; | 252 | m_CacheCleanTimer.Elapsed += CleanupExpiredFiles; |
252 | m_CacheCleanTimer.Start(); | 253 | m_CacheCleanTimer.Start(); |
253 | m_Running = true; | 254 | m_timerRunning = true; |
254 | } | 255 | } |
255 | } | 256 | } |
256 | } | 257 | } |
@@ -263,6 +264,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
263 | 264 | ||
264 | private void UpdateMemoryCache(string key, AssetBase asset) | 265 | private void UpdateMemoryCache(string key, AssetBase asset) |
265 | { | 266 | { |
267 | // NOTE DO NOT USE SLIDEEXPIRE option on current libomv | ||
266 | m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); | 268 | m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); |
267 | } | 269 | } |
268 | 270 | ||
@@ -480,12 +482,10 @@ namespace OpenSim.Region.CoreModules.Asset | |||
480 | asset = GetFromMemoryCache(id); | 482 | asset = GetFromMemoryCache(id); |
481 | 483 | ||
482 | if (asset == null && m_FileCacheEnabled) | 484 | if (asset == null && m_FileCacheEnabled) |
483 | { | ||
484 | asset = GetFromFileCache(id); | 485 | asset = GetFromFileCache(id); |
485 | 486 | ||
486 | if (m_MemoryCacheEnabled && asset != null) | 487 | if (m_MemoryCacheEnabled && asset != null) |
487 | UpdateMemoryCache(id, asset); | 488 | UpdateMemoryCache(id, asset); |
488 | } | ||
489 | 489 | ||
490 | if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) | 490 | if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) |
491 | { | 491 | { |
@@ -561,8 +561,12 @@ namespace OpenSim.Region.CoreModules.Asset | |||
561 | if (m_LogLevel >= 2) | 561 | if (m_LogLevel >= 2) |
562 | m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration); | 562 | m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration); |
563 | 563 | ||
564 | if(!m_Running) | 564 | lock(timerLock) |
565 | return; | 565 | { |
566 | if(!m_timerRunning || m_cleanupRunning) | ||
567 | return; | ||
568 | m_cleanupRunning = true; | ||
569 | } | ||
566 | // Purge all files last accessed prior to this point | 570 | // Purge all files last accessed prior to this point |
567 | DateTime purgeLine = DateTime.Now - m_FileExpiration; | 571 | DateTime purgeLine = DateTime.Now - m_FileExpiration; |
568 | 572 | ||
@@ -578,8 +582,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
578 | 582 | ||
579 | lock(timerLock) | 583 | lock(timerLock) |
580 | { | 584 | { |
581 | if(m_Running) | 585 | if(m_timerRunning) |
582 | m_CacheCleanTimer.Start(); | 586 | m_CacheCleanTimer.Start(); |
587 | m_cleanupRunning = false; | ||
583 | } | 588 | } |
584 | } | 589 | } |
585 | 590 | ||
@@ -816,13 +821,13 @@ namespace OpenSim.Region.CoreModules.Asset | |||
816 | 821 | ||
817 | s.ForEachSOG(delegate(SceneObjectGroup e) | 822 | s.ForEachSOG(delegate(SceneObjectGroup e) |
818 | { | 823 | { |
819 | if(!m_Running && !storeUncached) | 824 | if(!m_timerRunning && !storeUncached) |
820 | return; | 825 | return; |
821 | 826 | ||
822 | gatherer.AddForInspection(e); | 827 | gatherer.AddForInspection(e); |
823 | gatherer.GatherAll(); | 828 | gatherer.GatherAll(); |
824 | 829 | ||
825 | if(!m_Running && !storeUncached) | 830 | if(!m_timerRunning && !storeUncached) |
826 | return; | 831 | return; |
827 | 832 | ||
828 | foreach (UUID assetID in gatherer.GatheredUuids.Keys) | 833 | foreach (UUID assetID in gatherer.GatheredUuids.Keys) |
@@ -854,13 +859,13 @@ namespace OpenSim.Region.CoreModules.Asset | |||
854 | } | 859 | } |
855 | 860 | ||
856 | gatherer.GatheredUuids.Clear(); | 861 | gatherer.GatheredUuids.Clear(); |
857 | if(!m_Running && !storeUncached) | 862 | if(!m_timerRunning && !storeUncached) |
858 | return; | 863 | return; |
859 | 864 | ||
860 | if(!storeUncached) | 865 | if(!storeUncached) |
861 | Thread.Sleep(50); | 866 | Thread.Sleep(50); |
862 | }); | 867 | }); |
863 | if(!m_Running && !storeUncached) | 868 | if(!m_timerRunning && !storeUncached) |
864 | break; | 869 | break; |
865 | } | 870 | } |
866 | 871 | ||
@@ -905,16 +910,23 @@ namespace OpenSim.Region.CoreModules.Asset | |||
905 | { | 910 | { |
906 | List<string> outputLines = new List<string>(); | 911 | List<string> outputLines = new List<string>(); |
907 | 912 | ||
908 | double fileHitRate = (double)m_DiskHits / m_Requests * 100.0; | 913 | double invReq = 100.0 / m_Requests; |
914 | |||
915 | double fileHitRate = m_DiskHits * invReq; | ||
909 | outputLines.Add( | 916 | outputLines.Add( |
910 | string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); | 917 | string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); |
911 | 918 | ||
912 | if (m_MemoryCacheEnabled) | 919 | if (m_MemoryCacheEnabled) |
913 | { | 920 | { |
914 | double memHitRate = (double)m_MemoryHits / m_Requests * 100.0; | 921 | double HitRate = m_MemoryHits * invReq; |
922 | |||
923 | outputLines.Add( | ||
924 | string.Format("Memory Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests)); | ||
925 | |||
926 | HitRate += fileHitRate; | ||
915 | 927 | ||
916 | outputLines.Add( | 928 | outputLines.Add( |
917 | string.Format("Memory Hit Rate: {0}% for {1} requests", memHitRate.ToString("0.00"), m_Requests)); | 929 | string.Format("Total Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests)); |
918 | } | 930 | } |
919 | 931 | ||
920 | outputLines.Add( | 932 | outputLines.Add( |
@@ -1019,17 +1031,27 @@ namespace OpenSim.Region.CoreModules.Asset | |||
1019 | break; | 1031 | break; |
1020 | 1032 | ||
1021 | case "assets": | 1033 | case "assets": |
1022 | con.Output("Ensuring assets are cached for all scenes."); | 1034 | lock(timerLock) |
1035 | { | ||
1036 | if(m_cleanupRunning) | ||
1037 | { | ||
1038 | con.OutputFormat("FloatSam assets check already running"); | ||
1039 | return; | ||
1040 | } | ||
1041 | m_cleanupRunning = true; | ||
1042 | } | ||
1043 | |||
1044 | con.Output("FloatSam Ensuring assets are cached for all scenes."); | ||
1023 | 1045 | ||
1024 | WorkManager.RunInThread(delegate | 1046 | WorkManager.RunInThread(delegate |
1025 | { | 1047 | { |
1026 | bool wasRunning= false; | 1048 | bool wasRunning= false; |
1027 | lock(timerLock) | 1049 | lock(timerLock) |
1028 | { | 1050 | { |
1029 | if(m_Running) | 1051 | if(m_timerRunning) |
1030 | { | 1052 | { |
1031 | m_CacheCleanTimer.Stop(); | 1053 | m_CacheCleanTimer.Stop(); |
1032 | m_Running = false; | 1054 | m_timerRunning = false; |
1033 | wasRunning = true; | 1055 | wasRunning = true; |
1034 | Thread.Sleep(100); | 1056 | Thread.Sleep(100); |
1035 | } | 1057 | } |
@@ -1041,8 +1063,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
1041 | if(wasRunning) | 1063 | if(wasRunning) |
1042 | { | 1064 | { |
1043 | m_CacheCleanTimer.Start(); | 1065 | m_CacheCleanTimer.Start(); |
1044 | m_Running = true; | 1066 | m_timerRunning = true; |
1045 | } | 1067 | } |
1068 | m_cleanupRunning = false; | ||
1046 | } | 1069 | } |
1047 | con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); | 1070 | con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); |
1048 | }, null, "TouchAllSceneAssets"); | 1071 | }, null, "TouchAllSceneAssets"); |
diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example index db8d4db..6666812 100644 --- a/bin/config-include/FlotsamCache.ini.example +++ b/bin/config-include/FlotsamCache.ini.example | |||
@@ -20,15 +20,20 @@ | |||
20 | HitRateDisplay = 100 | 20 | HitRateDisplay = 100 |
21 | 21 | ||
22 | ; Set to false for no memory cache | 22 | ; Set to false for no memory cache |
23 | MemoryCacheEnabled = false | 23 | ; assets can be requested several times in short periods |
24 | ; so even a small memory cache is usefull | ||
25 | MemoryCacheEnabled = true | ||
24 | 26 | ||
25 | ; Set to false for no file cache | 27 | ; Set to false for no file cache |
26 | FileCacheEnabled = true | 28 | FileCacheEnabled = true |
27 | 29 | ||
28 | ; How long {in hours} to keep assets cached in memory, .5 == 30 minutes | 30 | ; How long {in hours} to keep assets cached in memory, .5 == 30 minutes |
29 | ; Optimization: for VPS or limited memory system installs set Timeout to .016 (1 minute) | 31 | ; even a few minutes may mean many assets loaded to memory, if not all. |
30 | ; increases performance without large memory impact | 32 | ; this is good if memory is not a problem. |
31 | MemoryCacheTimeout = 2 | 33 | ; if memory is a problem then a few seconds may actually save same. |
34 | ; reducing duplications. | ||
35 | ; see hit rates with console comand: fcache status | ||
36 | MemoryCacheTimeout = .001 // 3.6s ie around 4s (1s resolution) | ||
32 | 37 | ||
33 | ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes | 38 | ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes |
34 | ; Specify 0 if you do not want your disk cache to expire | 39 | ; Specify 0 if you do not want your disk cache to expire |