aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs')
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs128
1 files changed, 78 insertions, 50 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index d85d727..a0648f7 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -316,6 +316,12 @@ namespace Flotsam.RegionModules.AssetCache
316 LogException(e); 316 LogException(e);
317 } 317 }
318 } 318 }
319 catch (Exception e)
320 {
321 m_log.ErrorFormat(
322 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
323 asset.ID, e.Message, e.StackTrace);
324 }
319 } 325 }
320 326
321 public void Cache(AssetBase asset) 327 public void Cache(AssetBase asset)
@@ -368,13 +374,13 @@ namespace Flotsam.RegionModules.AssetCache
368 374
369 asset = (AssetBase)bformatter.Deserialize(stream); 375 asset = (AssetBase)bformatter.Deserialize(stream);
370 376
371 UpdateMemoryCache(id, asset);
372
373 m_DiskHits++; 377 m_DiskHits++;
374 } 378 }
375 catch (System.Runtime.Serialization.SerializationException e) 379 catch (System.Runtime.Serialization.SerializationException e)
376 { 380 {
377 LogException(e); 381 m_log.ErrorFormat(
382 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
383 filename, id, e.Message, e.StackTrace);
378 384
379 // If there was a problem deserializing the asset, the asset may 385 // If there was a problem deserializing the asset, the asset may
380 // either be corrupted OR was serialized under an old format 386 // either be corrupted OR was serialized under an old format
@@ -384,7 +390,9 @@ namespace Flotsam.RegionModules.AssetCache
384 } 390 }
385 catch (Exception e) 391 catch (Exception e)
386 { 392 {
387 LogException(e); 393 m_log.ErrorFormat(
394 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
395 filename, id, e.Message, e.StackTrace);
388 } 396 }
389 finally 397 finally
390 { 398 {
@@ -393,7 +401,6 @@ namespace Flotsam.RegionModules.AssetCache
393 } 401 }
394 } 402 }
395 403
396
397#if WAIT_ON_INPROGRESS_REQUESTS 404#if WAIT_ON_INPROGRESS_REQUESTS
398 // Check if we're already downloading this asset. If so, try to wait for it to 405 // Check if we're already downloading this asset. If so, try to wait for it to
399 // download. 406 // download.
@@ -416,7 +423,6 @@ namespace Flotsam.RegionModules.AssetCache
416 m_RequestsForInprogress++; 423 m_RequestsForInprogress++;
417 } 424 }
418#endif 425#endif
419
420 return asset; 426 return asset;
421 } 427 }
422 428
@@ -428,9 +434,15 @@ namespace Flotsam.RegionModules.AssetCache
428 434
429 if (m_MemoryCacheEnabled) 435 if (m_MemoryCacheEnabled)
430 asset = GetFromMemoryCache(id); 436 asset = GetFromMemoryCache(id);
431 else if (m_FileCacheEnabled) 437
438 if (asset == null && m_FileCacheEnabled)
439 {
432 asset = GetFromFileCache(id); 440 asset = GetFromFileCache(id);
433 441
442 if (m_MemoryCacheEnabled && asset != null)
443 UpdateMemoryCache(id, asset);
444 }
445
434 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 446 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
435 { 447 {
436 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; 448 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0;
@@ -445,7 +457,6 @@ namespace Flotsam.RegionModules.AssetCache
445 } 457 }
446 458
447 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); 459 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
448
449 } 460 }
450 461
451 return asset; 462 return asset;
@@ -459,7 +470,7 @@ namespace Flotsam.RegionModules.AssetCache
459 public void Expire(string id) 470 public void Expire(string id)
460 { 471 {
461 if (m_LogLevel >= 2) 472 if (m_LogLevel >= 2)
462 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id); 473 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id);
463 474
464 try 475 try
465 { 476 {
@@ -477,7 +488,9 @@ namespace Flotsam.RegionModules.AssetCache
477 } 488 }
478 catch (Exception e) 489 catch (Exception e)
479 { 490 {
480 LogException(e); 491 m_log.ErrorFormat(
492 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
493 id, e.Message, e.StackTrace);
481 } 494 }
482 } 495 }
483 496
@@ -597,31 +610,59 @@ namespace Flotsam.RegionModules.AssetCache
597 610
598 try 611 try
599 { 612 {
600 if (!Directory.Exists(directory)) 613 try
601 { 614 {
602 Directory.CreateDirectory(directory); 615 if (!Directory.Exists(directory))
616 {
617 Directory.CreateDirectory(directory);
618 }
619
620 stream = File.Open(tempname, FileMode.Create);
621 BinaryFormatter bformatter = new BinaryFormatter();
622 bformatter.Serialize(stream, asset);
603 } 623 }
624 catch (IOException e)
625 {
626 m_log.ErrorFormat(
627 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
628 asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
604 629
605 stream = File.Open(tempname, FileMode.Create); 630 return;
606 BinaryFormatter bformatter = new BinaryFormatter(); 631 }
607 bformatter.Serialize(stream, asset); 632 finally
608 stream.Close(); 633 {
609 634 if (stream != null)
610 // Now that it's written, rename it so that it can be found. 635 stream.Close();
611 File.Move(tempname, filename); 636 }
612 637
613 if (m_LogLevel >= 2) 638 try
614 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); 639 {
615 } 640 // Now that it's written, rename it so that it can be found.
616 catch (Exception e) 641 //
617 { 642 // File.Copy(tempname, filename, true);
618 LogException(e); 643 // File.Delete(tempname);
644 //
645 // For a brief period, this was done as a separate copy and then temporary file delete operation to
646 // avoid an IOException caused by move if some competing thread had already written the file.
647 // However, this causes exceptions on Windows when other threads attempt to read a file
648 // which is still being copied. So instead, go back to moving the file and swallow any IOException.
649 //
650 // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the
651 // filesystem.
652 File.Move(tempname, filename);
653
654 if (m_LogLevel >= 2)
655 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
656 }
657 catch (IOException)
658 {
659 // If we see an IOException here it's likely that some other competing thread has written the
660 // cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be
661 // signally by the earlier temporary file writing code.
662 }
619 } 663 }
620 finally 664 finally
621 { 665 {
622 if (stream != null)
623 stream.Close();
624
625 // Even if the write fails with an exception, we need to make sure 666 // Even if the write fails with an exception, we need to make sure
626 // that we release the lock on that file, otherwise it'll never get 667 // that we release the lock on that file, otherwise it'll never get
627 // cached 668 // cached
@@ -635,22 +676,9 @@ namespace Flotsam.RegionModules.AssetCache
635 waitEvent.Set(); 676 waitEvent.Set();
636 } 677 }
637#else 678#else
638 if (m_CurrentlyWriting.Contains(filename)) 679 m_CurrentlyWriting.Remove(filename);
639 {
640 m_CurrentlyWriting.Remove(filename);
641 }
642#endif 680#endif
643 } 681 }
644
645 }
646 }
647
648 private static void LogException(Exception e)
649 {
650 string[] text = e.ToString().Split(new char[] { '\n' });
651 foreach (string t in text)
652 {
653 m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t);
654 } 682 }
655 } 683 }
656 684
@@ -706,8 +734,7 @@ namespace Flotsam.RegionModules.AssetCache
706 s.ForEachSOG(delegate(SceneObjectGroup e) 734 s.ForEachSOG(delegate(SceneObjectGroup e)
707 { 735 {
708 gatherer.GatherAssetUuids(e, assets); 736 gatherer.GatherAssetUuids(e, assets);
709 } 737 });
710 );
711 } 738 }
712 739
713 foreach (UUID assetID in assets.Keys) 740 foreach (UUID assetID in assets.Keys)
@@ -740,7 +767,9 @@ namespace Flotsam.RegionModules.AssetCache
740 } 767 }
741 catch (Exception e) 768 catch (Exception e)
742 { 769 {
743 LogException(e); 770 m_log.ErrorFormat(
771 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
772 dir, m_CacheDirectory, e.Message, e.StackTrace);
744 } 773 }
745 } 774 }
746 775
@@ -752,7 +781,9 @@ namespace Flotsam.RegionModules.AssetCache
752 } 781 }
753 catch (Exception e) 782 catch (Exception e)
754 { 783 {
755 LogException(e); 784 m_log.ErrorFormat(
785 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
786 file, m_CacheDirectory, e.Message, e.StackTrace);
756 } 787 }
757 } 788 }
758 } 789 }
@@ -778,7 +809,7 @@ namespace Flotsam.RegionModules.AssetCache
778 809
779 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) 810 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
780 { 811 {
781 m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:"); 812 m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:");
782 813
783 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); 814 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
784 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); 815 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
@@ -849,7 +880,6 @@ namespace Flotsam.RegionModules.AssetCache
849 Util.FireAndForget(delegate { 880 Util.FireAndForget(delegate {
850 int assetsCached = CacheScenes(); 881 int assetsCached = CacheScenes();
851 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); 882 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
852
853 }); 883 });
854 884
855 break; 885 break;
@@ -904,7 +934,6 @@ namespace Flotsam.RegionModules.AssetCache
904 934
905 #region IAssetService Members 935 #region IAssetService Members
906 936
907
908 public AssetMetadata GetMetadata(string id) 937 public AssetMetadata GetMetadata(string id)
909 { 938 {
910 AssetBase asset = Get(id); 939 AssetBase asset = Get(id);
@@ -934,7 +963,6 @@ namespace Flotsam.RegionModules.AssetCache
934 Cache(asset); 963 Cache(asset);
935 964
936 return asset.ID; 965 return asset.ID;
937
938 } 966 }
939 967
940 public bool UpdateContent(string id, byte[] data) 968 public bool UpdateContent(string id, byte[] data)