From ac9d4a7783c376edaf8072fb5533603dfb368ab1 Mon Sep 17 00:00:00 2001 From: Archi Date: Tue, 14 Nov 2023 21:15:18 +0100 Subject: [PATCH] Actually make ArchiCacheable catch cancellation We intend to give the caller best result, operation canceled has no value for him, he can check if cancellation token he provided himself got canceled or not --- ArchiSteamFarm/Helpers/ArchiCacheable.cs | 33 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/ArchiSteamFarm/Helpers/ArchiCacheable.cs b/ArchiSteamFarm/Helpers/ArchiCacheable.cs index fb4fd38ac..f810836f6 100644 --- a/ArchiSteamFarm/Helpers/ArchiCacheable.cs +++ b/ArchiSteamFarm/Helpers/ArchiCacheable.cs @@ -23,6 +23,7 @@ using System; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; +using ArchiSteamFarm.Core; using JetBrains.Annotations; namespace ArchiSteamFarm.Helpers; @@ -58,7 +59,13 @@ public sealed class ArchiCacheable : IDisposable { return (true, InitializedValue); } - await InitSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + try { + await InitSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + } catch (OperationCanceledException e) { + ASF.ArchiLogger.LogGenericDebuggingException(e); + + return ReturnFailedValueFor(cacheFallback); + } try { if (IsInitialized && IsRecent) { @@ -68,18 +75,17 @@ public sealed class ArchiCacheable : IDisposable { (bool success, T? result) = await ResolveFunction(cancellationToken).ConfigureAwait(false); if (!success) { - return cacheFallback switch { - ECacheFallback.DefaultForType => (false, default(T?)), - ECacheFallback.FailedNow => (false, result), - ECacheFallback.SuccessPreviously => (false, InitializedValue), - _ => throw new InvalidOperationException(nameof(cacheFallback)) - }; + return ReturnFailedValueFor(cacheFallback, result); } InitializedValue = result; InitializedAt = DateTime.UtcNow; return (true, result); + } catch (OperationCanceledException e) { + ASF.ArchiLogger.LogGenericDebuggingException(e); + + return ReturnFailedValueFor(cacheFallback); } finally { InitSemaphore.Release(); } @@ -103,4 +109,17 @@ public sealed class ArchiCacheable : IDisposable { InitSemaphore.Release(); } } + + private (bool Success, T? Result) ReturnFailedValueFor(ECacheFallback cacheFallback, T? result = default) { + if (!Enum.IsDefined(typeof(ECacheFallback), cacheFallback)) { + throw new InvalidEnumArgumentException(nameof(cacheFallback), (int) cacheFallback, typeof(ECacheFallback)); + } + + return cacheFallback switch { + ECacheFallback.DefaultForType => (false, default(T?)), + ECacheFallback.FailedNow => (false, result), + ECacheFallback.SuccessPreviously => (false, InitializedValue), + _ => throw new InvalidOperationException(nameof(cacheFallback)) + }; + } }