diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 80 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | 16 |
2 files changed, 61 insertions, 35 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index da39202..22c301b 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -357,8 +357,6 @@ namespace Flotsam.RegionModules.AssetCache | |||
357 | 357 | ||
358 | asset = (AssetBase)bformatter.Deserialize(stream); | 358 | asset = (AssetBase)bformatter.Deserialize(stream); |
359 | 359 | ||
360 | UpdateMemoryCache(id, asset); | ||
361 | |||
362 | m_DiskHits++; | 360 | m_DiskHits++; |
363 | } | 361 | } |
364 | catch (System.Runtime.Serialization.SerializationException e) | 362 | catch (System.Runtime.Serialization.SerializationException e) |
@@ -419,9 +417,15 @@ namespace Flotsam.RegionModules.AssetCache | |||
419 | 417 | ||
420 | if (m_MemoryCacheEnabled) | 418 | if (m_MemoryCacheEnabled) |
421 | asset = GetFromMemoryCache(id); | 419 | asset = GetFromMemoryCache(id); |
420 | |||
422 | if (asset == null && m_FileCacheEnabled) | 421 | if (asset == null && m_FileCacheEnabled) |
422 | { | ||
423 | asset = GetFromFileCache(id); | 423 | asset = GetFromFileCache(id); |
424 | 424 | ||
425 | if (m_MemoryCacheEnabled && asset != null) | ||
426 | UpdateMemoryCache(id, asset); | ||
427 | } | ||
428 | |||
425 | if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) | 429 | if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) |
426 | { | 430 | { |
427 | m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; | 431 | m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; |
@@ -589,33 +593,59 @@ namespace Flotsam.RegionModules.AssetCache | |||
589 | 593 | ||
590 | try | 594 | try |
591 | { | 595 | { |
592 | if (!Directory.Exists(directory)) | 596 | try |
593 | { | 597 | { |
594 | Directory.CreateDirectory(directory); | 598 | if (!Directory.Exists(directory)) |
599 | { | ||
600 | Directory.CreateDirectory(directory); | ||
601 | } | ||
602 | |||
603 | stream = File.Open(tempname, FileMode.Create); | ||
604 | BinaryFormatter bformatter = new BinaryFormatter(); | ||
605 | bformatter.Serialize(stream, asset); | ||
595 | } | 606 | } |
607 | catch (IOException e) | ||
608 | { | ||
609 | m_log.ErrorFormat( | ||
610 | "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.", | ||
611 | asset.ID, tempname, filename, directory, e.Message, e.StackTrace); | ||
596 | 612 | ||
597 | stream = File.Open(tempname, FileMode.Create); | 613 | return; |
598 | BinaryFormatter bformatter = new BinaryFormatter(); | 614 | } |
599 | bformatter.Serialize(stream, asset); | 615 | finally |
600 | stream.Close(); | 616 | { |
601 | 617 | if (stream != null) | |
602 | // Now that it's written, rename it so that it can be found. | 618 | stream.Close(); |
603 | File.Move(tempname, filename); | 619 | } |
604 | 620 | ||
605 | if (m_LogLevel >= 2) | 621 | try |
606 | m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); | 622 | { |
607 | } | 623 | // Now that it's written, rename it so that it can be found. |
608 | catch (Exception e) | 624 | // |
609 | { | 625 | // File.Copy(tempname, filename, true); |
610 | m_log.ErrorFormat( | 626 | // File.Delete(tempname); |
611 | "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to cache. Directory {1}, tempname {2}, filename {3}. Exception {4} {5}.", | 627 | // |
612 | asset.ID, directory, tempname, filename, e.Message, e.StackTrace); | 628 | // For a brief period, this was done as a separate copy and then temporary file delete operation to |
629 | // avoid an IOException caused by move if some competing thread had already written the file. | ||
630 | // However, this causes exceptions on Windows when other threads attempt to read a file | ||
631 | // which is still being copied. So instead, go back to moving the file and swallow any IOException. | ||
632 | // | ||
633 | // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the | ||
634 | // filesystem. | ||
635 | File.Move(tempname, filename); | ||
636 | |||
637 | if (m_LogLevel >= 2) | ||
638 | m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); | ||
639 | } | ||
640 | catch (IOException) | ||
641 | { | ||
642 | // If we see an IOException here it's likely that some other competing thread has written the | ||
643 | // cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be | ||
644 | // signally by the earlier temporary file writing code. | ||
645 | } | ||
613 | } | 646 | } |
614 | finally | 647 | finally |
615 | { | 648 | { |
616 | if (stream != null) | ||
617 | stream.Close(); | ||
618 | |||
619 | // Even if the write fails with an exception, we need to make sure | 649 | // Even if the write fails with an exception, we need to make sure |
620 | // that we release the lock on that file, otherwise it'll never get | 650 | // that we release the lock on that file, otherwise it'll never get |
621 | // cached | 651 | // cached |
@@ -629,13 +659,9 @@ namespace Flotsam.RegionModules.AssetCache | |||
629 | waitEvent.Set(); | 659 | waitEvent.Set(); |
630 | } | 660 | } |
631 | #else | 661 | #else |
632 | if (m_CurrentlyWriting.Contains(filename)) | 662 | m_CurrentlyWriting.Remove(filename); |
633 | { | ||
634 | m_CurrentlyWriting.Remove(filename); | ||
635 | } | ||
636 | #endif | 663 | #endif |
637 | } | 664 | } |
638 | |||
639 | } | 665 | } |
640 | } | 666 | } |
641 | 667 | ||
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 63b0c31..2ff1920 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | |||
@@ -65,18 +65,18 @@ namespace OpenSim.Region.CoreModules.Asset.Tests | |||
65 | config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); | 65 | config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); |
66 | 66 | ||
67 | m_cache = new FlotsamAssetCache(); | 67 | m_cache = new FlotsamAssetCache(); |
68 | m_scene = SceneSetupHelpers.SetupScene(); | 68 | m_scene = SceneHelpers.SetupScene(); |
69 | SceneSetupHelpers.SetupSceneModules(m_scene, config, m_cache); | 69 | SceneHelpers.SetupSceneModules(m_scene, config, m_cache); |
70 | } | 70 | } |
71 | 71 | ||
72 | [Test] | 72 | [Test] |
73 | public void TestCacheAsset() | 73 | public void TestCacheAsset() |
74 | { | 74 | { |
75 | TestHelper.InMethod(); | 75 | TestHelpers.InMethod(); |
76 | // log4net.Config.XmlConfigurator.Configure(); | 76 | // log4net.Config.XmlConfigurator.Configure(); |
77 | 77 | ||
78 | AssetBase asset = AssetHelpers.CreateAsset(); | 78 | AssetBase asset = AssetHelpers.CreateAsset(); |
79 | asset.ID = TestHelper.ParseTail(0x1).ToString(); | 79 | asset.ID = TestHelpers.ParseTail(0x1).ToString(); |
80 | 80 | ||
81 | // Check we don't get anything before the asset is put in the cache | 81 | // Check we don't get anything before the asset is put in the cache |
82 | AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString()); | 82 | AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString()); |
@@ -93,11 +93,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests | |||
93 | [Test] | 93 | [Test] |
94 | public void TestExpireAsset() | 94 | public void TestExpireAsset() |
95 | { | 95 | { |
96 | TestHelper.InMethod(); | 96 | TestHelpers.InMethod(); |
97 | // log4net.Config.XmlConfigurator.Configure(); | 97 | // log4net.Config.XmlConfigurator.Configure(); |
98 | 98 | ||
99 | AssetBase asset = AssetHelpers.CreateAsset(); | 99 | AssetBase asset = AssetHelpers.CreateAsset(); |
100 | asset.ID = TestHelper.ParseTail(0x2).ToString(); | 100 | asset.ID = TestHelpers.ParseTail(0x2).ToString(); |
101 | 101 | ||
102 | m_cache.Store(asset); | 102 | m_cache.Store(asset); |
103 | 103 | ||
@@ -110,11 +110,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests | |||
110 | [Test] | 110 | [Test] |
111 | public void TestClearCache() | 111 | public void TestClearCache() |
112 | { | 112 | { |
113 | TestHelper.InMethod(); | 113 | TestHelpers.InMethod(); |
114 | // log4net.Config.XmlConfigurator.Configure(); | 114 | // log4net.Config.XmlConfigurator.Configure(); |
115 | 115 | ||
116 | AssetBase asset = AssetHelpers.CreateAsset(); | 116 | AssetBase asset = AssetHelpers.CreateAsset(); |
117 | asset.ID = TestHelper.ParseTail(0x2).ToString(); | 117 | asset.ID = TestHelpers.ParseTail(0x2).ToString(); |
118 | 118 | ||
119 | m_cache.Store(asset); | 119 | m_cache.Store(asset); |
120 | 120 | ||