diff --git a/src/Sitko.Core.Storage/Sitko.Core.Storage.csproj b/src/Sitko.Core.Storage/Sitko.Core.Storage.csproj index 8e5bf620..8c5a74c3 100644 --- a/src/Sitko.Core.Storage/Sitko.Core.Storage.csproj +++ b/src/Sitko.Core.Storage/Sitko.Core.Storage.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Sitko.Core.Storage/Storage.cs b/src/Sitko.Core.Storage/Storage.cs index 88678daf..f0683554 100644 --- a/src/Sitko.Core.Storage/Storage.cs +++ b/src/Sitko.Core.Storage/Storage.cs @@ -5,6 +5,7 @@ using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Nito.AsyncEx; using Sitko.Core.Storage.Cache; namespace Sitko.Core.Storage @@ -16,6 +17,7 @@ public abstract class Storage : IStorage, IAsyncDisposable where T : Stora private readonly T _options; private StorageNode? _tree; private DateTimeOffset? _treeLastBuild; + private AsyncLock _treeLock = new(); protected Storage(T options, ILogger> logger, IStorageCache? cache) { @@ -39,7 +41,7 @@ public async Task SaveAsync(Stream file, string fileName, string pa itemMetadata); var result = await SaveStorageItemAsync(file, path, destinationPath, storageItem, itemMetadata); - await BuildStorageTreeAsync(); + await RebuildStorageTreeAsync(); return result; } @@ -50,7 +52,7 @@ private async Task SaveStorageItemAsync(Stream file, string path, s file.Seek(0, SeekOrigin.Begin); await DoSaveAsync(destinationPath, file, JsonSerializer.Serialize(metadata)); Logger.LogInformation("File saved to {Path}", path); - if (_cache != null && storageItem.FilePath != null) + if (_cache != null && !string.IsNullOrEmpty(storageItem.FilePath)) { await _cache.RemoveItemAsync(storageItem.FilePath); } @@ -128,7 +130,7 @@ public async Task DeleteAsync(string filePath) } var result = await DoDeleteAsync(filePath); - await BuildStorageTreeAsync(); + await RebuildStorageTreeAsync(); return result; } @@ -199,10 +201,23 @@ public async Task> GetDirectoryContentsAsync(string pat return current?.Children ?? new StorageNode[0]; } + private async Task RebuildStorageTreeAsync() + { + if (_tree != null) + { + await BuildStorageTreeAsync(); + } + } + private async Task BuildStorageTreeAsync() { - _tree = await DoBuildStorageTreeAsync(); - _treeLastBuild = DateTimeOffset.UtcNow; + using (await _treeLock.LockAsync()) + { + Logger.LogInformation("Start building storage tree"); + _tree = await DoBuildStorageTreeAsync(); + _treeLastBuild = DateTimeOffset.UtcNow; + Logger.LogInformation("Done building storage tree"); + } } protected abstract Task DoBuildStorageTreeAsync();