From a44332540662df24d1fd49bcb409510461e038f7 Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Wed, 24 Jan 2024 09:38:50 +0100 Subject: [PATCH 1/4] Switched to a more performant locking library --- src/Kiota.Builder/Caching/DocumentCachingProvider.cs | 6 +++--- src/Kiota.Builder/Kiota.Builder.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs index 7bb280c983..31412a5da2 100644 --- a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs +++ b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using NeoSmart.AsyncLock; +using AsyncKeyedLock; namespace Kiota.Builder.Caching; @@ -39,7 +39,7 @@ private async Task GetDocumentInternalAsync(Uri documentUri, string inte { var hashedUrl = BitConverter.ToString((HashAlgorithm.Value ?? throw new InvalidOperationException("unable to get hash algorithm")).ComputeHash(Encoding.UTF8.GetBytes(documentUri.ToString()))).Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase); var target = Path.Combine(Path.GetTempPath(), Constants.TempDirectoryName, "cache", intermediateFolderName, hashedUrl, fileName); - var currentLock = _locks.GetOrAdd(target, _ => new AsyncLock()); + var currentLock = _locks.GetOrAdd(target, _ => new AsyncNonKeyedLocker()); using (await currentLock.LockAsync(token).ConfigureAwait(false)) {// if multiple clients are being updated for the same description, we'll have concurrent download of the file without the lock if (!File.Exists(target) || couldNotDelete) @@ -67,7 +67,7 @@ private async Task GetDocumentInternalAsync(Uri documentUri, string inte return await GetDocumentInternalAsync(documentUri, intermediateFolderName, fileName, couldNotDelete, accept, token).ConfigureAwait(false); } } - private static readonly ConcurrentDictionary _locks = new(StringComparer.OrdinalIgnoreCase); + private static readonly ConcurrentDictionary _locks = new(StringComparer.OrdinalIgnoreCase); private async Task DownloadDocumentFromSourceAsync(Uri documentUri, string target, string? accept, CancellationToken token) { Logger.LogDebug("cache file {CacheFile} not found, downloading from {Url}", target, documentUri); diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index 2fef97de62..75cca50566 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -35,6 +35,7 @@ $(NoWarn);CS8785;NU5048;NU5104;CA1724;CA1055;CA1848;CA1308;CA1822 + @@ -47,7 +48,6 @@ - From e9287a776d6564afd9e89a5a4431ecbc2fabb0bf Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Wed, 24 Jan 2024 14:25:33 +0100 Subject: [PATCH 2/4] Update src/Kiota.Builder/Caching/DocumentCachingProvider.cs Co-authored-by: Vincent Biret --- src/Kiota.Builder/Caching/DocumentCachingProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs index 31412a5da2..eb9537cd0c 100644 --- a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs +++ b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs @@ -67,7 +67,7 @@ private async Task GetDocumentInternalAsync(Uri documentUri, string inte return await GetDocumentInternalAsync(documentUri, intermediateFolderName, fileName, couldNotDelete, accept, token).ConfigureAwait(false); } } - private static readonly ConcurrentDictionary _locks = new(StringComparer.OrdinalIgnoreCase); + private static readonly AsyncKeyedLocker _locks = new(); private async Task DownloadDocumentFromSourceAsync(Uri documentUri, string target, string? accept, CancellationToken token) { Logger.LogDebug("cache file {CacheFile} not found, downloading from {Url}", target, documentUri); From d8e2d97b976d384a08f0e8c9052f7c5822ebe123 Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Wed, 24 Jan 2024 14:25:40 +0100 Subject: [PATCH 3/4] Update src/Kiota.Builder/Caching/DocumentCachingProvider.cs Co-authored-by: Vincent Biret --- src/Kiota.Builder/Caching/DocumentCachingProvider.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs index eb9537cd0c..64a94747bf 100644 --- a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs +++ b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs @@ -39,8 +39,7 @@ private async Task GetDocumentInternalAsync(Uri documentUri, string inte { var hashedUrl = BitConverter.ToString((HashAlgorithm.Value ?? throw new InvalidOperationException("unable to get hash algorithm")).ComputeHash(Encoding.UTF8.GetBytes(documentUri.ToString()))).Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase); var target = Path.Combine(Path.GetTempPath(), Constants.TempDirectoryName, "cache", intermediateFolderName, hashedUrl, fileName); - var currentLock = _locks.GetOrAdd(target, _ => new AsyncNonKeyedLocker()); - using (await currentLock.LockAsync(token).ConfigureAwait(false)) + using (await _locks.LockAsync(target, token).ConfigureAwait(false)) {// if multiple clients are being updated for the same description, we'll have concurrent download of the file without the lock if (!File.Exists(target) || couldNotDelete) return await DownloadDocumentFromSourceAsync(documentUri, target, accept, token).ConfigureAwait(false); From f804e31ccf166464f18c7d3c2c5db257e0b3ab6e Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Wed, 24 Jan 2024 14:28:10 +0100 Subject: [PATCH 4/4] Added pooling to keyed locking to improve performance and reduce memory allocations. --- src/Kiota.Builder/Caching/DocumentCachingProvider.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs index 64a94747bf..7a0a93fafc 100644 --- a/src/Kiota.Builder/Caching/DocumentCachingProvider.cs +++ b/src/Kiota.Builder/Caching/DocumentCachingProvider.cs @@ -1,13 +1,12 @@ using System; -using System.Collections.Concurrent; using System.IO; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; using AsyncKeyedLock; +using Microsoft.Extensions.Logging; namespace Kiota.Builder.Caching; @@ -66,7 +65,11 @@ private async Task GetDocumentInternalAsync(Uri documentUri, string inte return await GetDocumentInternalAsync(documentUri, intermediateFolderName, fileName, couldNotDelete, accept, token).ConfigureAwait(false); } } - private static readonly AsyncKeyedLocker _locks = new(); + private static readonly AsyncKeyedLocker _locks = new(o => + { + o.PoolSize = 20; + o.PoolInitialFill = 1; + }); private async Task DownloadDocumentFromSourceAsync(Uri documentUri, string target, string? accept, CancellationToken token) { Logger.LogDebug("cache file {CacheFile} not found, downloading from {Url}", target, documentUri);