Updates the cache file paths to be resolved behind a lazy so that there's proper locking in place for accessing the value, this also makes the code a little nicer.

This commit is contained in:
Shannon
2017-10-09 16:01:22 +11:00
parent ce81416368
commit 422219ab21
2 changed files with 34 additions and 72 deletions

View File

@@ -41,8 +41,8 @@ namespace Umbraco.Core
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IRuntimeCacheProvider _runtimeCache; private readonly IRuntimeCacheProvider _runtimeCache;
private readonly ProfilingLogger _logger; private readonly ProfilingLogger _logger;
private string _pluginListFilePath; private readonly Lazy<string> _pluginListFilePath = new Lazy<string>(GetPluginListFilePath);
private string _pluginHashFilePath; private readonly Lazy<string> _pluginHashFilePath = new Lazy<string>(GetPluginHashFilePath);
private readonly object _typesLock = new object(); private readonly object _typesLock = new object();
private readonly Dictionary<TypeListKey, TypeList> _types = new Dictionary<TypeListKey, TypeList>(); private readonly Dictionary<TypeListKey, TypeList> _types = new Dictionary<TypeListKey, TypeList>();
@@ -69,8 +69,6 @@ namespace Umbraco.Core
_runtimeCache = runtimeCache; _runtimeCache = runtimeCache;
_logger = logger; _logger = logger;
var pluginListFile = GetPluginListFilePath();
if (detectChanges) if (detectChanges)
{ {
//first check if the cached hash is string.Empty, if it is then we need //first check if the cached hash is string.Empty, if it is then we need
@@ -82,8 +80,8 @@ namespace Umbraco.Core
// if the hash has changed, clear out the persisted list no matter what, this will force // if the hash has changed, clear out the persisted list no matter what, this will force
// rescanning of all plugin types including lazy ones. // rescanning of all plugin types including lazy ones.
// http://issues.umbraco.org/issue/U4-4789 // http://issues.umbraco.org/issue/U4-4789
if(File.Exists(pluginListFile)) if(File.Exists(_pluginListFilePath.Value))
File.Delete(pluginListFile); File.Delete(_pluginListFilePath.Value);
WriteCachePluginsHash(); WriteCachePluginsHash();
} }
@@ -93,8 +91,8 @@ namespace Umbraco.Core
// if the hash has changed, clear out the persisted list no matter what, this will force // if the hash has changed, clear out the persisted list no matter what, this will force
// rescanning of all plugin types including lazy ones. // rescanning of all plugin types including lazy ones.
// http://issues.umbraco.org/issue/U4-4789 // http://issues.umbraco.org/issue/U4-4789
if (File.Exists(pluginListFile)) if (File.Exists(_pluginListFilePath.Value))
File.Delete(pluginListFile); File.Delete(_pluginListFilePath.Value);
// always set to true if we're not detecting (generally only for testing) // always set to true if we're not detecting (generally only for testing)
RequiresRescanning = true; RequiresRescanning = true;
@@ -187,11 +185,10 @@ namespace Umbraco.Core
{ {
if (_cachedAssembliesHash != null) if (_cachedAssembliesHash != null)
return _cachedAssembliesHash; return _cachedAssembliesHash;
if (File.Exists(_pluginHashFilePath.Value) == false) return string.Empty;
var filePath = GetPluginHashFilePath(); var hash = File.ReadAllText(_pluginHashFilePath.Value, Encoding.UTF8);
if (File.Exists(filePath) == false) return string.Empty;
var hash = File.ReadAllText(filePath, Encoding.UTF8);
_cachedAssembliesHash = hash; _cachedAssembliesHash = hash;
return _cachedAssembliesHash; return _cachedAssembliesHash;
@@ -229,9 +226,8 @@ namespace Umbraco.Core
/// Writes the assembly hash file. /// Writes the assembly hash file.
/// </summary> /// </summary>
private void WriteCachePluginsHash() private void WriteCachePluginsHash()
{ {
var filePath = GetPluginHashFilePath(); File.WriteAllText(_pluginHashFilePath.Value, CurrentAssembliesHash, Encoding.UTF8);
File.WriteAllText(filePath, CurrentAssembliesHash, Encoding.UTF8);
} }
/// <summary> /// <summary>
@@ -351,8 +347,7 @@ namespace Umbraco.Core
{ {
try try
{ {
var filePath = GetPluginListFilePath(); File.Delete(_pluginListFilePath.Value);
File.Delete(filePath);
} }
catch catch
{ {
@@ -366,12 +361,11 @@ namespace Umbraco.Core
internal Dictionary<Tuple<string, string>, IEnumerable<string>> ReadCache() internal Dictionary<Tuple<string, string>, IEnumerable<string>> ReadCache()
{ {
var cache = new Dictionary<Tuple<string, string>, IEnumerable<string>>(); var cache = new Dictionary<Tuple<string, string>, IEnumerable<string>>();
var filePath = GetPluginListFilePath(); if (File.Exists(_pluginListFilePath.Value) == false)
if (File.Exists(filePath) == false)
return cache; return cache;
using (var stream = GetFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, ListFileOpenReadTimeout)) using (var stream = GetFileStream(_pluginListFilePath.Value, FileMode.Open, FileAccess.Read, FileShare.Read, ListFileOpenReadTimeout))
using (var reader = new StreamReader(stream)) using (var reader = new StreamReader(stream))
{ {
while (true) while (true)
@@ -414,24 +408,17 @@ namespace Umbraco.Core
/// <remarks>Generally only used for resetting cache, for example during the install process.</remarks> /// <remarks>Generally only used for resetting cache, for example during the install process.</remarks>
public void ClearPluginCache() public void ClearPluginCache()
{ {
var path = GetPluginListFilePath(); if (File.Exists(_pluginListFilePath.Value))
if (File.Exists(path)) File.Delete(_pluginListFilePath.Value);
File.Delete(path);
if (File.Exists(_pluginHashFilePath.Value))
path = GetPluginHashFilePath(); File.Delete(_pluginHashFilePath.Value);
if (File.Exists(path))
File.Delete(path);
_runtimeCache.ClearCacheItem(CacheKey); _runtimeCache.ClearCacheItem(CacheKey);
} }
private string GetPluginListFilePath() private static string GetPluginListFilePath()
{ {
//if it's already set then return it - we don't care about locking here
//if 2 threads do this at the same time it won't hurt
if (_pluginListFilePath != null)
return _pluginListFilePath;
string pluginListFilePath; string pluginListFilePath;
switch (GlobalSettings.LocalTempStorageLocation) switch (GlobalSettings.LocalTempStorageLocation)
{ {
@@ -461,17 +448,11 @@ namespace Umbraco.Core
if (Directory.Exists(folder) == false) if (Directory.Exists(folder) == false)
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
_pluginListFilePath = pluginListFilePath; return pluginListFilePath;
return _pluginListFilePath;
} }
private string GetPluginHashFilePath() private static string GetPluginHashFilePath()
{ {
//if it's already set then return it - we don't care about locking here
//if 2 threads do this at the same time it won't hurt
if (_pluginHashFilePath != null)
return _pluginHashFilePath;
string pluginHashFilePath; string pluginHashFilePath;
switch (GlobalSettings.LocalTempStorageLocation) switch (GlobalSettings.LocalTempStorageLocation)
{ {
@@ -500,16 +481,13 @@ namespace Umbraco.Core
throw new InvalidOperationException("The folder could not be determined for the file " + pluginHashFilePath); throw new InvalidOperationException("The folder could not be determined for the file " + pluginHashFilePath);
if (Directory.Exists(folder) == false) if (Directory.Exists(folder) == false)
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
_pluginHashFilePath = pluginHashFilePath; return pluginHashFilePath;
return _pluginHashFilePath;
} }
internal void WriteCache() internal void WriteCache()
{ {
var filePath = GetPluginListFilePath(); using (var stream = GetFileStream(_pluginListFilePath.Value, FileMode.Create, FileAccess.Write, FileShare.None, ListFileOpenWriteTimeout))
using (var stream = GetFileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, ListFileOpenWriteTimeout))
using (var writer = new StreamWriter(stream)) using (var writer = new StreamWriter(stream))
{ {
foreach (var typeList in _types.Values) foreach (var typeList in _types.Values)
@@ -755,7 +733,7 @@ namespace Umbraco.Core
// else proceed, // else proceed,
typeList = new TypeList(baseType, attributeType); typeList = new TypeList(baseType, attributeType);
var scan = RequiresRescanning || File.Exists(GetPluginListFilePath()) == false; var scan = RequiresRescanning || File.Exists(_pluginListFilePath.Value) == false;
if (scan) if (scan)
{ {

View File

@@ -40,7 +40,7 @@ namespace Umbraco.Core.Sync
private bool _syncing; private bool _syncing;
private bool _released; private bool _released;
private readonly ProfilingLogger _profilingLogger; private readonly ProfilingLogger _profilingLogger;
private string _distCacheFilePath; private Lazy<string> _distCacheFilePath = new Lazy<string>(GetDistCacheFilePath);
protected DatabaseServerMessengerOptions Options { get; private set; } protected DatabaseServerMessengerOptions Options { get; private set; }
protected ApplicationContext ApplicationContext { get { return _appContext; } } protected ApplicationContext ApplicationContext { get { return _appContext; } }
@@ -462,10 +462,9 @@ namespace Umbraco.Core.Sync
/// </remarks> /// </remarks>
private void ReadLastSynced() private void ReadLastSynced()
{ {
var path = SyncFilePath; if (File.Exists(_distCacheFilePath.Value) == false) return;
if (File.Exists(path) == false) return;
var content = File.ReadAllText(path); var content = File.ReadAllText(_distCacheFilePath.Value);
int last; int last;
if (int.TryParse(content, out last)) if (int.TryParse(content, out last))
_lastId = last; _lastId = last;
@@ -480,7 +479,7 @@ namespace Umbraco.Core.Sync
/// </remarks> /// </remarks>
private void SaveLastSynced(int id) private void SaveLastSynced(int id)
{ {
File.WriteAllText(SyncFilePath, id.ToString(CultureInfo.InvariantCulture)); File.WriteAllText(_distCacheFilePath.Value, id.ToString(CultureInfo.InvariantCulture));
_lastId = id; _lastId = id;
} }
@@ -500,22 +499,8 @@ namespace Umbraco.Core.Sync
+ "/D" + AppDomain.CurrentDomain.Id // eg 22 + "/D" + AppDomain.CurrentDomain.Id // eg 22
+ "] " + Guid.NewGuid().ToString("N").ToUpper(); // make it truly unique + "] " + Guid.NewGuid().ToString("N").ToUpper(); // make it truly unique
/// <summary> private static string GetDistCacheFilePath()
/// Gets the sync file path for the local server.
/// </summary>
/// <returns>The sync file path for the local server.</returns>
private string SyncFilePath
{ {
get { return GetDistCacheFilePath(); }
}
private string GetDistCacheFilePath()
{
//if it's already set then return it - we don't care about locking here
//if 2 threads do this at the same time it won't hurt
if (_distCacheFilePath != null)
return _distCacheFilePath;
var fileName = HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt"; var fileName = HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt";
string distCacheFilePath; string distCacheFilePath;
@@ -547,8 +532,7 @@ namespace Umbraco.Core.Sync
if (Directory.Exists(folder) == false) if (Directory.Exists(folder) == false)
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
_distCacheFilePath = distCacheFilePath; return distCacheFilePath;
return _distCacheFilePath;
} }
#endregion #endregion