aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Asset
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Asset')
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs80
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs16
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