diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheCommonEventsHub.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheCommonEventsHub.cs index d63fabdb..34379715 100644 --- a/src/ZiggyCreatures.FusionCache/Events/FusionCacheCommonEventsHub.cs +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheCommonEventsHub.cs @@ -36,6 +36,7 @@ protected FusionCacheCommonEventsHub(IFusionCache cache, FusionCacheOptions opti /// /// The event for a cache set. /// + /// The event args has not been strongly typed to avoid breaking changes but it can be cast as an instance of when subscribed to. public event EventHandler? Set; /// @@ -43,13 +44,13 @@ protected FusionCacheCommonEventsHub(IFusionCache cache, FusionCacheOptions opti /// public event EventHandler? Remove; - internal virtual void OnHit(string operationId, string key, bool isStale, Activity? activity) + internal virtual void OnHit(string operationId, string key, bool isStale, Activity? activity, FusionCacheEntryMetadata? metadata) { // ACTIVITY activity?.AddTag(Tags.Names.Hit, true); activity?.AddTag(Tags.Names.Stale, isStale); - Hit?.SafeExecute(operationId, key, _cache, new FusionCacheEntryHitEventArgs(key, isStale), nameof(Hit), _logger, _errorsLogLevel, _syncExecution); + Hit?.SafeExecute(operationId, key, _cache, new FusionCacheEntryHitEventArgs(key, isStale, metadata), nameof(Hit), _logger, _errorsLogLevel, _syncExecution); } internal virtual void OnMiss(string operationId, string key, Activity? activity) @@ -60,9 +61,9 @@ internal virtual void OnMiss(string operationId, string key, Activity? activity) Miss?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key), nameof(Miss), _logger, _errorsLogLevel, _syncExecution); } - internal virtual void OnSet(string operationId, string key) + internal virtual void OnSet(string operationId, string key, FusionCacheEntryMetadata? metadata) { - Set?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key), nameof(Set), _logger, _errorsLogLevel, _syncExecution); + Set?.SafeExecute(operationId, key, _cache, new FusionCacheEntrySetEventArgs(key, metadata), nameof(Set), _logger, _errorsLogLevel, _syncExecution); } internal virtual void OnRemove(string operationId, string key) diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheDistributedEventsHub.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheDistributedEventsHub.cs index 0959793b..7235ade4 100644 --- a/src/ZiggyCreatures.FusionCache/Events/FusionCacheDistributedEventsHub.cs +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheDistributedEventsHub.cs @@ -61,12 +61,12 @@ internal void OnDeserializationError(string? operationId, string? key) DeserializationError?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key ?? string.Empty), nameof(DeserializationError), _logger, _errorsLogLevel, _syncExecution); } - internal override void OnHit(string operationId, string key, bool isStale, Activity? activity) + internal override void OnHit(string operationId, string key, bool isStale, Activity? activity, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterDistributedHit.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId, new KeyValuePair(Tags.Names.Stale, isStale)); - base.OnHit(operationId, key, isStale, activity); + base.OnHit(operationId, key, isStale, activity, metadata); } internal override void OnMiss(string operationId, string key, Activity? activity) @@ -77,12 +77,12 @@ internal override void OnMiss(string operationId, string key, Activity? activity base.OnMiss(operationId, key, activity); } - internal override void OnSet(string operationId, string key) + internal override void OnSet(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterDistributedSet.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId); - base.OnSet(operationId, key); + base.OnSet(operationId, key, metadata); } internal override void OnRemove(string operationId, string key) diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryEvictionEventArgs.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryEvictionEventArgs.cs index 884a71be..67551c63 100644 --- a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryEvictionEventArgs.cs +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryEvictionEventArgs.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Caching.Memory; +using ZiggyCreatures.Caching.Fusion.Internals; namespace ZiggyCreatures.Caching.Fusion.Events; @@ -15,10 +16,23 @@ public class FusionCacheEntryEvictionEventArgs /// The reason for the eviction. /// The value being evicted from the cache. public FusionCacheEntryEvictionEventArgs(string key, EvictionReason reason, object? value) + : this(key, reason, value, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The cache key related to the event. + /// The reason for the eviction. + /// The value being evicted from the cache. + /// The metadata related to the cache entry evicted (if any). + public FusionCacheEntryEvictionEventArgs(string key, EvictionReason reason, object? value, FusionCacheEntryMetadata? metadata) : base(key) { Reason = reason; Value = value; + Metadata = metadata; } /// @@ -30,4 +44,9 @@ public FusionCacheEntryEvictionEventArgs(string key, EvictionReason reason, obje /// The value being evicted from the cache. /// public object? Value { get; } + + /// + /// The metadata related to the cache entry evicted (if any). + /// + public FusionCacheEntryMetadata? Metadata { get; } } diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryExpirationEventArgs.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryExpirationEventArgs.cs new file mode 100644 index 00000000..ab950261 --- /dev/null +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryExpirationEventArgs.cs @@ -0,0 +1,25 @@ +using ZiggyCreatures.Caching.Fusion.Internals; + +namespace ZiggyCreatures.Caching.Fusion.Events; + +/// +/// The specific object for events related to cache entries' expirations. +/// +public class FusionCacheEntryExpirationEventArgs : FusionCacheEntryEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The cache key related to the event. + /// The metadata related to the cache entry expired (if any). + public FusionCacheEntryExpirationEventArgs(string key, FusionCacheEntryMetadata? metadata) + : base(key) + { + Metadata = metadata; + } + + /// + /// The metadata related to the cache entry expired (if any). + /// + public FusionCacheEntryMetadata? Metadata { get; } +} diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryHitEventArgs.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryHitEventArgs.cs index 81809cfc..8ca538e1 100644 --- a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryHitEventArgs.cs +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntryHitEventArgs.cs @@ -1,4 +1,6 @@ -namespace ZiggyCreatures.Caching.Fusion.Events; +using ZiggyCreatures.Caching.Fusion.Internals; + +namespace ZiggyCreatures.Caching.Fusion.Events; /// /// The specific object for events related to cache entries' hits (eg: with a cache key and a stale flag). @@ -11,13 +13,30 @@ public class FusionCacheEntryHitEventArgs : FusionCacheEntryEventArgs /// The cache key related to the event. /// A flag that indicates if the cache hit was for a fresh or stale entry. public FusionCacheEntryHitEventArgs(string key, bool isStale) + : this(key, isStale, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The cache key related to the event. + /// A flag that indicates if the cache hit was for a fresh or stale entry. + /// The metadata related to the cache entry hit (if any). + public FusionCacheEntryHitEventArgs(string key, bool isStale, FusionCacheEntryMetadata? metadata) : base(key) { IsStale = isStale; + Metadata = metadata; } /// /// A flag that indicates if the cache hit was for a fresh or stale entry. /// public bool IsStale { get; } + + /// + /// The metadata related to the cache entry hit (if any). + /// + public FusionCacheEntryMetadata? Metadata { get; } } diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntrySetEventArgs.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntrySetEventArgs.cs new file mode 100644 index 00000000..54eedbbf --- /dev/null +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEntrySetEventArgs.cs @@ -0,0 +1,25 @@ +using ZiggyCreatures.Caching.Fusion.Internals; + +namespace ZiggyCreatures.Caching.Fusion.Events; + +/// +/// The specific object for events related to cache entries' set. +/// +public class FusionCacheEntrySetEventArgs : FusionCacheEntryEventArgs +{ + /// + /// Initializes a new instance of the class. + /// + /// The cache key related to the event. + /// The metadata related to the cache entry set (if any). + public FusionCacheEntrySetEventArgs(string key, FusionCacheEntryMetadata? metadata) + : base(key) + { + Metadata = metadata; + } + + /// + /// The metadata related to the cache entry set (if any). + /// + public FusionCacheEntryMetadata? Metadata { get; } +} diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEventsHub.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEventsHub.cs index 9dc23125..ba611e7c 100644 --- a/src/ZiggyCreatures.FusionCache/Events/FusionCacheEventsHub.cs +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheEventsHub.cs @@ -90,7 +90,7 @@ public FusionCacheEventsHub(IFusionCache cache, FusionCacheOptions options, ILog /// public event EventHandler? Clear; - internal void OnFailSafeActivate(string operationId, string key) + internal void OnFailSafeActivate(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterFailSafeActivate.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId); @@ -114,7 +114,7 @@ internal void OnFactoryError(string operationId, string key) FactoryError?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key), nameof(FactoryError), _logger, _errorsLogLevel, _syncExecution); } - internal void OnFactorySuccess(string operationId, string key) + internal void OnFactorySuccess(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterFactorySuccess.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId, new KeyValuePair(Tags.Names.OperationBackground, false)); @@ -130,7 +130,7 @@ internal void OnBackgroundFactoryError(string operationId, string key) BackgroundFactoryError?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key), nameof(BackgroundFactoryError), _logger, _errorsLogLevel, _syncExecution); } - internal void OnBackgroundFactorySuccess(string operationId, string key) + internal void OnBackgroundFactorySuccess(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterFactorySuccess.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId, new KeyValuePair(Tags.Names.OperationBackground, true)); @@ -138,7 +138,7 @@ internal void OnBackgroundFactorySuccess(string operationId, string key) BackgroundFactorySuccess?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key), nameof(BackgroundFactorySuccess), _logger, _errorsLogLevel, _syncExecution); } - internal void OnEagerRefresh(string operationId, string key) + internal void OnEagerRefresh(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterEagerRefresh.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId); @@ -178,12 +178,12 @@ internal void OnClear(string operationId) // OVERRIDES - internal override void OnHit(string operationId, string key, bool isStale, Activity? activity) + internal override void OnHit(string operationId, string key, bool isStale, Activity? activity, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterHit.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId, new KeyValuePair(Tags.Names.Stale, isStale)); - base.OnHit(operationId, key, isStale, activity); + base.OnHit(operationId, key, isStale, activity, metadata); } internal override void OnMiss(string operationId, string key, Activity? activity) @@ -194,12 +194,12 @@ internal override void OnMiss(string operationId, string key, Activity? activity base.OnMiss(operationId, key, activity); } - internal override void OnSet(string operationId, string key) + internal override void OnSet(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterSet.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId); - base.OnSet(operationId, key); + base.OnSet(operationId, key, metadata); } internal override void OnRemove(string operationId, string key) diff --git a/src/ZiggyCreatures.FusionCache/Events/FusionCacheMemoryEventsHub.cs b/src/ZiggyCreatures.FusionCache/Events/FusionCacheMemoryEventsHub.cs index 4b8ca484..93a9064d 100644 --- a/src/ZiggyCreatures.FusionCache/Events/FusionCacheMemoryEventsHub.cs +++ b/src/ZiggyCreatures.FusionCache/Events/FusionCacheMemoryEventsHub.cs @@ -31,6 +31,7 @@ public FusionCacheMemoryEventsHub(IFusionCache cache, FusionCacheOptions options /// /// The event for a manual cache Expire() call. /// + /// The event args has not been strongly typed to avoid breaking changes but it can be cast as an instance of when subscribed to. public event EventHandler? Expire; /// @@ -42,28 +43,28 @@ public bool HasEvictionSubscribers() return Eviction is not null; } - internal void OnEviction(string operationId, string key, EvictionReason reason, object? value) + internal void OnEviction(string operationId, string key, EvictionReason reason, object? value, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterMemoryEvict.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId, new KeyValuePair(Tags.Names.MemoryEvictReason, reason.ToString())); - Eviction?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEvictionEventArgs(key, reason, value), nameof(Eviction), _logger, _errorsLogLevel, _syncExecution); + Eviction?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEvictionEventArgs(key, reason, value, metadata), nameof(Eviction), _logger, _errorsLogLevel, _syncExecution); } - internal void OnExpire(string operationId, string key) + internal void OnExpire(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterMemoryExpire.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId); - Expire?.SafeExecute(operationId, key, _cache, new FusionCacheEntryEventArgs(key), nameof(Expire), _logger, _errorsLogLevel, _syncExecution); + Expire?.SafeExecute(operationId, key, _cache, new FusionCacheEntryExpirationEventArgs(key, metadata), nameof(Expire), _logger, _errorsLogLevel, _syncExecution); } - internal override void OnHit(string operationId, string key, bool isStale, Activity? activity) + internal override void OnHit(string operationId, string key, bool isStale, Activity? activity, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterMemoryHit.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId, new KeyValuePair(Tags.Names.Stale, isStale)); - base.OnHit(operationId, key, isStale, activity); + base.OnHit(operationId, key, isStale, activity, metadata); } internal override void OnMiss(string operationId, string key, Activity? activity) @@ -74,12 +75,12 @@ internal override void OnMiss(string operationId, string key, Activity? activity base.OnMiss(operationId, key, activity); } - internal override void OnSet(string operationId, string key) + internal override void OnSet(string operationId, string key, FusionCacheEntryMetadata? metadata) { // METRIC Metrics.CounterMemorySet.Maybe()?.AddWithCommonTags(1, _cache.CacheName, _cache.InstanceId); - base.OnSet(operationId, key); + base.OnSet(operationId, key, metadata); } internal override void OnRemove(string operationId, string key) diff --git a/src/ZiggyCreatures.FusionCache/FusionCache.cs b/src/ZiggyCreatures.FusionCache/FusionCache.cs index 62eecea1..b7dfc21b 100644 --- a/src/ZiggyCreatures.FusionCache/FusionCache.cs +++ b/src/ZiggyCreatures.FusionCache/FusionCache.cs @@ -398,7 +398,7 @@ internal BackplaneAccessor? BackplaneAccessor if (entry is not null) { // EVENT - _events.OnFailSafeActivate(operationId, key); + _events.OnFailSafeActivate(operationId, key, entry.Metadata); return entry; } @@ -536,8 +536,8 @@ private void CompleteBackgroundFactory(string operationId, string key, F } // EVENT - _events.OnBackgroundFactorySuccess(operationId, key); - _events.OnSet(operationId, key); + _events.OnBackgroundFactorySuccess(operationId, key, lateEntry.Metadata); + _events.OnSet(operationId, key, lateEntry.Metadata); } } finally diff --git a/src/ZiggyCreatures.FusionCache/FusionCacheEntryOptions.cs b/src/ZiggyCreatures.FusionCache/FusionCacheEntryOptions.cs index f499b816..1be5d381 100644 --- a/src/ZiggyCreatures.FusionCache/FusionCacheEntryOptions.cs +++ b/src/ZiggyCreatures.FusionCache/FusionCacheEntryOptions.cs @@ -971,7 +971,8 @@ internal DateTimeOffset GetMemoryAbsoluteExpiration(out bool incoherentFailSafeM res.RegisterPostEvictionCallback( (key, entry, reason, state) => { - ((FusionCacheMemoryEventsHub?)state)?.OnEviction(string.Empty, key.ToString() ?? "", reason, ((IFusionCacheMemoryEntry?)entry)?.Value); + var memoryEntry = (IFusionCacheMemoryEntry?)entry; + ((FusionCacheMemoryEventsHub?)state)?.OnEviction(string.Empty, key.ToString() ?? "", reason, memoryEntry?.Value, memoryEntry?.Metadata); }, events ); diff --git a/src/ZiggyCreatures.FusionCache/FusionCache_Async.cs b/src/ZiggyCreatures.FusionCache/FusionCache_Async.cs index 0a2b6cd7..f4459a71 100644 --- a/src/ZiggyCreatures.FusionCache/FusionCache_Async.cs +++ b/src/ZiggyCreatures.FusionCache/FusionCache_Async.cs @@ -15,7 +15,7 @@ public partial class FusionCache private void ExecuteEagerRefreshWithAsyncFactory(string operationId, string key, string originalKey, string[]? tags, Func, CancellationToken, Task> factory, FusionCacheEntryOptions options, IFusionCacheMemoryEntry memoryEntry, object memoryLockObj) { // EVENT - _events.OnEagerRefresh(operationId, key); + _events.OnEagerRefresh(operationId, key, memoryEntry.Metadata); _ = Task.Run(async () => { @@ -132,7 +132,7 @@ private void ExecuteEagerRefreshWithAsyncFactory(string operationId, str _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry!.IsStale(), activity); + _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity, memoryEntry!.Metadata); return memoryEntry; } @@ -155,7 +155,7 @@ private void ExecuteEagerRefreshWithAsyncFactory(string operationId, str // --> USE IT (WITHOUT SAVING IT, SINCE THE ALREADY RUNNING FACTORY WILL DO IT ANYWAY) // EVENT - _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry.IsStale(), activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -178,7 +178,7 @@ private void ExecuteEagerRefreshWithAsyncFactory(string operationId, str _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry!.IsStale(), activity); + _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity, memoryEntry!.Metadata); return memoryEntry; } @@ -206,7 +206,6 @@ private void ExecuteEagerRefreshWithAsyncFactory(string operationId, str if (distributedEntryIsValid) { - isStale = false; entry = FusionCacheMemoryEntry.CreateFromOtherEntry(distributedEntry!, options); } else @@ -283,7 +282,7 @@ private void ExecuteEagerRefreshWithAsyncFactory(string operationId, str entry = FusionCacheMemoryEntry.CreateFromOptions(value, GetSerializedValueFromValue(operationId, key, value, options), null, ctx.Tags, options, isStale, ctx.LastModified?.UtcTicks, ctx.ETag); // EVENTS - _events.OnFactorySuccess(operationId, key); + _events.OnFactorySuccess(operationId, key, entry.Metadata); } } catch (OperationCanceledException exc) @@ -344,12 +343,12 @@ private void ExecuteEagerRefreshWithAsyncFactory(string operationId, str // EVENT _events.OnMiss(operationId, key, activity); - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, entry?.Metadata); } else if (entry is not null) { // EVENT - _events.OnHit(operationId, key, isStale || entry.IsStale(), activity); + _events.OnHit(operationId, key, isStale || entry.IsStale(), activity, entry.Metadata); } else { @@ -493,7 +492,7 @@ public async ValueTask GetOrSetAsync(string key, TValue defaultV _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity); + _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity, memoryEntry!.Metadata); return memoryEntry; } @@ -509,7 +508,7 @@ public async ValueTask GetOrSetAsync(string key, TValue defaultV _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry (expired)", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, true, activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -549,7 +548,7 @@ public async ValueTask GetOrSetAsync(string key, TValue defaultV } // EVENT - _events.OnHit(operationId, key, distributedEntry!.IsStale(), activity); + _events.OnHit(operationId, key, distributedEntry!.IsStale(), activity, memoryEntry.Metadata); return memoryEntry; } @@ -573,7 +572,7 @@ public async ValueTask GetOrSetAsync(string key, TValue defaultV } // EVENT - _events.OnHit(operationId, key, true, activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -585,7 +584,7 @@ public async ValueTask GetOrSetAsync(string key, TValue defaultV _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry (expired)", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, true, activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -740,7 +739,7 @@ public async ValueTask SetAsync(string key, TValue value, FusionCacheEnt } // EVENT - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, entry.Metadata); } catch (Exception exc) { @@ -1329,7 +1328,7 @@ private ValueTask DistributedExpireEntryAsync(string operationId, string key, Fu _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): memory entry updated from distributed", CacheName, InstanceId, operationId, key); // EVENT - _events.Memory.OnSet(operationId, key); + _events.Memory.OnSet(operationId, key, memoryEntry.Metadata); return (false, false, true); } diff --git a/src/ZiggyCreatures.FusionCache/FusionCache_Sync.cs b/src/ZiggyCreatures.FusionCache/FusionCache_Sync.cs index af29447f..d594c7d2 100644 --- a/src/ZiggyCreatures.FusionCache/FusionCache_Sync.cs +++ b/src/ZiggyCreatures.FusionCache/FusionCache_Sync.cs @@ -15,7 +15,7 @@ public partial class FusionCache private void ExecuteEagerRefreshWithSyncFactory(string operationId, string key, string originalKey, string[]? tags, Func, CancellationToken, TValue> factory, FusionCacheEntryOptions options, IFusionCacheMemoryEntry memoryEntry, object memoryLockObj) { // EVENT - _events.OnEagerRefresh(operationId, key); + _events.OnEagerRefresh(operationId, key, memoryEntry.Metadata); _ = Task.Run(() => { @@ -132,7 +132,7 @@ private void ExecuteEagerRefreshWithSyncFactory(string operationId, stri _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry!.IsStale(), activity); + _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity, memoryEntry!.Metadata); return memoryEntry; } @@ -155,7 +155,7 @@ private void ExecuteEagerRefreshWithSyncFactory(string operationId, stri // --> USE IT (WITHOUT SAVING IT, SINCE THE ALREADY RUNNING FACTORY WILL DO IT ANYWAY) // EVENT - _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry.IsStale(), activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -178,7 +178,7 @@ private void ExecuteEagerRefreshWithSyncFactory(string operationId, stri _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry!.IsStale(), activity); + _events.OnHit(operationId, key, memoryEntryIsValid == false || memoryEntry!.IsStale(), activity, memoryEntry!.Metadata); return memoryEntry; } @@ -283,7 +283,7 @@ private void ExecuteEagerRefreshWithSyncFactory(string operationId, stri entry = FusionCacheMemoryEntry.CreateFromOptions(value, GetSerializedValueFromValue(operationId, key, value, options), null, ctx.Tags, options, isStale, ctx.LastModified?.UtcTicks, ctx.ETag); // EVENTS - _events.OnFactorySuccess(operationId, key); + _events.OnFactorySuccess(operationId, key, entry.Metadata); } } catch (OperationCanceledException exc) @@ -344,12 +344,12 @@ private void ExecuteEagerRefreshWithSyncFactory(string operationId, stri // EVENT _events.OnMiss(operationId, key, activity); - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, entry?.Metadata); } else if (entry is not null) { // EVENT - _events.OnHit(operationId, key, isStale || entry.IsStale(), activity); + _events.OnHit(operationId, key, isStale || entry.IsStale(), activity, entry.Metadata); } else { @@ -493,7 +493,7 @@ public TValue GetOrSet(string key, TValue defaultValue, FusionCacheEntry _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity); + _events.OnHit(operationId, key, memoryEntry!.IsStale(), activity, memoryEntry!.Metadata); return memoryEntry; } @@ -509,7 +509,7 @@ public TValue GetOrSet(string key, TValue defaultValue, FusionCacheEntry _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry (expired)", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, true, activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -549,7 +549,7 @@ public TValue GetOrSet(string key, TValue defaultValue, FusionCacheEntry } // EVENT - _events.OnHit(operationId, key, distributedEntry!.IsStale(), activity); + _events.OnHit(operationId, key, distributedEntry!.IsStale(), activity, memoryEntry.Metadata); return memoryEntry; } @@ -573,7 +573,7 @@ public TValue GetOrSet(string key, TValue defaultValue, FusionCacheEntry } // EVENT - _events.OnHit(operationId, key, true, activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -585,7 +585,7 @@ public TValue GetOrSet(string key, TValue defaultValue, FusionCacheEntry _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): using memory entry (expired)", CacheName, InstanceId, operationId, key); // EVENT - _events.OnHit(operationId, key, true, activity); + _events.OnHit(operationId, key, true, activity, memoryEntry.Metadata); return memoryEntry; } @@ -740,7 +740,7 @@ public void Set(string key, TValue value, FusionCacheEntryOptions? optio } // EVENT - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, entry.Metadata); } catch (Exception exc) { @@ -1329,7 +1329,7 @@ private void DistributedExpireEntry(string operationId, string key, FusionCacheE _logger.Log(LogLevel.Trace, "FUSION [N={CacheName} I={CacheInstanceId}] (O={CacheOperationId} K={CacheKey}): memory entry updated from distributed", CacheName, InstanceId, operationId, key); // EVENT - _events.Memory.OnSet(operationId, key); + _events.Memory.OnSet(operationId, key, memoryEntry.Metadata); return (false, false, true); } diff --git a/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Async.cs b/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Async.cs index 5c1039e1..82d8c64c 100644 --- a/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Async.cs +++ b/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Async.cs @@ -131,7 +131,7 @@ public async ValueTask SetEntryAsync(string operationId, string ke await _cache.SetAsync(MaybeProcessCacheKey(key), data, distributedOptions, ct).ConfigureAwait(false); // EVENT - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, distributedEntry.Metadata); }, "setting entry in distributed" + isBackground.ToString(" (background)"), options, @@ -236,7 +236,7 @@ public async ValueTask SetEntryAsync(string operationId, string ke // EVENT if (entry is not null) { - _events.OnHit(operationId, key, isValid == false, activity); + _events.OnHit(operationId, key, isValid == false, activity, entry.Metadata); } else { diff --git a/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Sync.cs b/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Sync.cs index 1f44607e..dcd5888b 100644 --- a/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Sync.cs +++ b/src/ZiggyCreatures.FusionCache/Internals/Distributed/DistributedCacheAccessor_Sync.cs @@ -124,7 +124,7 @@ public bool SetEntry(string operationId, string key, IFusionCacheEntry e _cache.Set(MaybeProcessCacheKey(key), data, distributedOptions); // EVENT - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, entry.Metadata); }, "setting entry in distributed" + isBackground.ToString(" (background)"), options, @@ -220,7 +220,7 @@ public bool SetEntry(string operationId, string key, IFusionCacheEntry e // EVENT if (entry is not null) { - _events.OnHit(operationId, key, isValid == false, activity); + _events.OnHit(operationId, key, isValid == false, activity, entry.Metadata); } else { diff --git a/src/ZiggyCreatures.FusionCache/Internals/Memory/MemoryCacheAccessor.cs b/src/ZiggyCreatures.FusionCache/Internals/Memory/MemoryCacheAccessor.cs index 3d3f7db1..395cf471 100644 --- a/src/ZiggyCreatures.FusionCache/Internals/Memory/MemoryCacheAccessor.cs +++ b/src/ZiggyCreatures.FusionCache/Internals/Memory/MemoryCacheAccessor.cs @@ -82,7 +82,7 @@ public void SetEntry(string operationId, string key, IFusionCacheMemoryE } // EVENT - _events.OnSet(operationId, key); + _events.OnSet(operationId, key, entry.Metadata); } catch (Exception exc) { @@ -107,7 +107,7 @@ public void SetEntry(string operationId, string key, IFusionCacheMemoryE // EVENT if (entry is not null) { - _events.OnHit(operationId, key, entry.IsLogicallyExpired(), activity); + _events.OnHit(operationId, key, entry.IsLogicallyExpired(), activity, entry.Metadata); } else { @@ -164,7 +164,7 @@ public void SetEntry(string operationId, string key, IFusionCacheMemoryE // EVENT if (entry is not null) { - _events.OnHit(operationId, key, isValid == false, activity); + _events.OnHit(operationId, key, isValid == false, activity, entry.Metadata); } else { @@ -244,7 +244,7 @@ public bool ExpireEntry(string operationId, string key, long? timestampThreshold } // EVENT - _events.OnExpire(operationId, key); + _events.OnExpire(operationId, key, entry.Metadata); return true; } diff --git a/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Async.cs b/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Async.cs index f13d90c0..22e152b6 100644 --- a/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Async.cs +++ b/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Async.cs @@ -26,7 +26,7 @@ public async Task EntryEventsWorkAsync() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onRemove = (s, e) => stats.RecordAction(EntryActionKind.Remove); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); EventHandler onFactoryError = (s, e) => stats.RecordAction(EntryActionKind.FactoryError); @@ -94,14 +94,14 @@ public async Task EntryEventsWorkAsync() cache.Events.FactoryError -= onFactoryError; cache.Events.FactorySuccess -= onFactorySuccess; - Assert.Equal(4, stats.Data[EntryActionKind.Miss]); - Assert.Equal(2, stats.Data[EntryActionKind.HitNormal]); - Assert.Equal(2, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(2, stats.Data[EntryActionKind.Set]); - Assert.Equal(2, stats.Data[EntryActionKind.Remove]); - Assert.Equal(2, stats.Data[EntryActionKind.FailSafeActivate]); - Assert.Equal(2, stats.Data[EntryActionKind.FactoryError]); - Assert.Equal(1, stats.Data[EntryActionKind.FactorySuccess]); + Assert.Equal(4, stats[EntryActionKind.Miss]); + Assert.Equal(2, stats[EntryActionKind.HitNormal]); + Assert.Equal(2, stats[EntryActionKind.HitStale]); + Assert.Equal(2, stats[EntryActionKind.Set]); + Assert.Equal(2, stats[EntryActionKind.Remove]); + Assert.Equal(2, stats[EntryActionKind.FailSafeActivate]); + Assert.Equal(2, stats[EntryActionKind.FactoryError]); + Assert.Equal(1, stats[EntryActionKind.FactorySuccess]); } [Fact] @@ -121,7 +121,7 @@ public async Task GetOrSetAsync() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onRemove = (s, e) => stats.RecordAction(EntryActionKind.Remove); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); @@ -147,9 +147,9 @@ public async Task GetOrSetAsync() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(2, stats.Data[EntryActionKind.Miss]); - Assert.Equal(2, stats.Data[EntryActionKind.Set]); - Assert.Equal(4, stats.Data.Values.Sum()); + Assert.Equal(2, stats[EntryActionKind.Miss]); + Assert.Equal(2, stats[EntryActionKind.Set]); + Assert.Equal(4, stats.Total); } [Fact] @@ -169,7 +169,7 @@ public async Task GetOrSetStaleAsync() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onRemove = (s, e) => stats.RecordAction(EntryActionKind.Remove); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); @@ -197,10 +197,10 @@ public async Task GetOrSetStaleAsync() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(0, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(1, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data[EntryActionKind.Set]); - Assert.Equal(2, stats.Data.Values.Sum()); + Assert.Equal(0, stats[EntryActionKind.HitStale]); + Assert.Equal(1, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats[EntryActionKind.Set]); + Assert.Equal(2, stats.Total); } [Fact] @@ -241,8 +241,8 @@ public async Task TryGetAsync() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(1, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data.Values.Sum()); + Assert.Equal(1, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats.Total); } [Fact] @@ -289,8 +289,8 @@ public async Task TryGetStaleFailSafeAsync() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(1, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(1, stats.Data.Values.Sum()); + Assert.Equal(1, stats[EntryActionKind.HitStale]); + Assert.Equal(1, stats.Total); } [Fact] @@ -337,8 +337,8 @@ public async Task TryGetStaleNoAllowStaleOnReadOnlyAsync() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(1, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data.Values.Sum()); + Assert.Equal(1, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats.Total); } [Fact] @@ -358,7 +358,7 @@ public async Task MemoryLevelEventsAsync() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); // SETUP HANDLERS cache.Events.Memory.Miss += onMiss; @@ -374,9 +374,9 @@ public async Task MemoryLevelEventsAsync() cache.Events.Memory.Hit -= onHit; cache.Events.Memory.Set -= onSet; - Assert.Equal(2, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data[EntryActionKind.Set]); - Assert.Equal(3, stats.Data.Values.Sum()); + Assert.Equal(2, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats[EntryActionKind.Set]); + Assert.Equal(3, stats.Total); } [Fact] @@ -431,10 +431,10 @@ public async Task BackplaneEventsAsync() cache3.Events.Backplane.MessagePublished -= onMessagePublished3; cache3.Events.Backplane.MessageReceived -= onMessageReceived3; - Assert.Equal(1, stats2.Data[EntryActionKind.BackplaneMessagePublished]); - Assert.Equal(2, stats2.Data[EntryActionKind.BackplaneMessageReceived]); - Assert.Equal(0, stats3.Data[EntryActionKind.BackplaneMessagePublished]); - Assert.Equal(3, stats3.Data[EntryActionKind.BackplaneMessageReceived]); + Assert.Equal(1, stats2[EntryActionKind.BackplaneMessagePublished]); + Assert.Equal(2, stats2[EntryActionKind.BackplaneMessageReceived]); + Assert.Equal(0, stats3[EntryActionKind.BackplaneMessagePublished]); + Assert.Equal(3, stats3[EntryActionKind.BackplaneMessageReceived]); } [Fact] @@ -446,7 +446,7 @@ public async Task StaleHitForOldStaleDataAsync() using var cache = new FusionCache(new FusionCacheOptions() { EnableSyncEventHandlersExecution = true }); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); // SETUP HANDLERS @@ -474,9 +474,9 @@ public async Task StaleHitForOldStaleDataAsync() Assert.Equal(21, secondValue); Assert.Equal(21, thirdValue); Assert.Equal(21, fourthValue); - Assert.Equal(1, stats.Data[EntryActionKind.Set]); - Assert.Equal(1, stats.Data[EntryActionKind.HitNormal]); - Assert.Equal(2, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(1, stats.Data[EntryActionKind.FailSafeActivate]); + Assert.Equal(1, stats[EntryActionKind.Set]); + Assert.Equal(1, stats[EntryActionKind.HitNormal]); + Assert.Equal(2, stats[EntryActionKind.HitStale]); + Assert.Equal(1, stats[EntryActionKind.FailSafeActivate]); } } diff --git a/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Sync.cs b/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Sync.cs index a54a63fe..ae96af32 100644 --- a/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Sync.cs +++ b/tests/ZiggyCreatures.FusionCache.Tests/EventsTests_Sync.cs @@ -26,7 +26,7 @@ public void EntryEventsWork() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onRemove = (s, e) => stats.RecordAction(EntryActionKind.Remove); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); EventHandler onFactoryError = (s, e) => stats.RecordAction(EntryActionKind.FactoryError); @@ -94,14 +94,14 @@ public void EntryEventsWork() cache.Events.FactoryError -= onFactoryError; cache.Events.FactorySuccess -= onFactorySuccess; - Assert.Equal(4, stats.Data[EntryActionKind.Miss]); - Assert.Equal(2, stats.Data[EntryActionKind.HitNormal]); - Assert.Equal(2, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(2, stats.Data[EntryActionKind.Set]); - Assert.Equal(2, stats.Data[EntryActionKind.Remove]); - Assert.Equal(2, stats.Data[EntryActionKind.FailSafeActivate]); - Assert.Equal(2, stats.Data[EntryActionKind.FactoryError]); - Assert.Equal(1, stats.Data[EntryActionKind.FactorySuccess]); + Assert.Equal(4, stats[EntryActionKind.Miss]); + Assert.Equal(2, stats[EntryActionKind.HitNormal]); + Assert.Equal(2, stats[EntryActionKind.HitStale]); + Assert.Equal(2, stats[EntryActionKind.Set]); + Assert.Equal(2, stats[EntryActionKind.Remove]); + Assert.Equal(2, stats[EntryActionKind.FailSafeActivate]); + Assert.Equal(2, stats[EntryActionKind.FactoryError]); + Assert.Equal(1, stats[EntryActionKind.FactorySuccess]); } [Fact] @@ -121,7 +121,7 @@ public void GetOrSet() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onRemove = (s, e) => stats.RecordAction(EntryActionKind.Remove); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); @@ -147,9 +147,9 @@ public void GetOrSet() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(2, stats.Data[EntryActionKind.Miss]); - Assert.Equal(2, stats.Data[EntryActionKind.Set]); - Assert.Equal(4, stats.Data.Values.Sum()); + Assert.Equal(2, stats[EntryActionKind.Miss]); + Assert.Equal(2, stats[EntryActionKind.Set]); + Assert.Equal(4, stats.Total); } [Fact] @@ -169,7 +169,7 @@ public void GetOrSetStale() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onRemove = (s, e) => stats.RecordAction(EntryActionKind.Remove); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); @@ -197,10 +197,10 @@ public void GetOrSetStale() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(0, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(1, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data[EntryActionKind.Set]); - Assert.Equal(2, stats.Data.Values.Sum()); + Assert.Equal(0, stats[EntryActionKind.HitStale]); + Assert.Equal(1, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats[EntryActionKind.Set]); + Assert.Equal(2, stats.Total); } [Fact] @@ -241,8 +241,8 @@ public void TryGet() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(1, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data.Values.Sum()); + Assert.Equal(1, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats.Total); } [Fact] @@ -289,8 +289,8 @@ public void TryGetStaleFailSafe() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(1, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(1, stats.Data.Values.Sum()); + Assert.Equal(1, stats[EntryActionKind.HitStale]); + Assert.Equal(1, stats.Total); } [Fact] @@ -337,8 +337,8 @@ public void TryGetStaleNoAllowStaleOnReadOnly() cache.Events.Remove -= onRemove; cache.Events.FailSafeActivate -= onFailSafeActivate; - Assert.Equal(1, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data.Values.Sum()); + Assert.Equal(1, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats.Total); } [Fact] @@ -358,7 +358,7 @@ public void MemoryLevelEvents() EventHandler onMiss = (s, e) => stats.RecordAction(EntryActionKind.Miss); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); // SETUP HANDLERS cache.Events.Memory.Miss += onMiss; @@ -374,9 +374,9 @@ public void MemoryLevelEvents() cache.Events.Memory.Hit -= onHit; cache.Events.Memory.Set -= onSet; - Assert.Equal(2, stats.Data[EntryActionKind.Miss]); - Assert.Equal(1, stats.Data[EntryActionKind.Set]); - Assert.Equal(3, stats.Data.Values.Sum()); + Assert.Equal(2, stats[EntryActionKind.Miss]); + Assert.Equal(1, stats[EntryActionKind.Set]); + Assert.Equal(3, stats.Total); } [Fact] @@ -431,10 +431,10 @@ public void BackplaneEvents() cache3.Events.Backplane.MessagePublished -= onMessagePublished3; cache3.Events.Backplane.MessageReceived -= onMessageReceived3; - Assert.Equal(1, stats2.Data[EntryActionKind.BackplaneMessagePublished]); - Assert.Equal(2, stats2.Data[EntryActionKind.BackplaneMessageReceived]); - Assert.Equal(0, stats3.Data[EntryActionKind.BackplaneMessagePublished]); - Assert.Equal(3, stats3.Data[EntryActionKind.BackplaneMessageReceived]); + Assert.Equal(1, stats2[EntryActionKind.BackplaneMessagePublished]); + Assert.Equal(2, stats2[EntryActionKind.BackplaneMessageReceived]); + Assert.Equal(0, stats3[EntryActionKind.BackplaneMessagePublished]); + Assert.Equal(3, stats3[EntryActionKind.BackplaneMessageReceived]); } [Fact] @@ -446,7 +446,7 @@ public void StaleHitForOldStaleData() using var cache = new FusionCache(new FusionCacheOptions() { EnableSyncEventHandlersExecution = true }); EventHandler onHit = (s, e) => stats.RecordAction(e.IsStale ? EntryActionKind.HitStale : EntryActionKind.HitNormal); - EventHandler onSet = (s, e) => stats.RecordAction(EntryActionKind.Set); + EventHandler onSet = (s, e) => stats.RecordActionIf(EntryActionKind.Set, e is FusionCacheEntrySetEventArgs); EventHandler onFailSafeActivate = (s, e) => stats.RecordAction(EntryActionKind.FailSafeActivate); // SETUP HANDLERS @@ -474,9 +474,9 @@ public void StaleHitForOldStaleData() Assert.Equal(21, secondValue); Assert.Equal(21, thirdValue); Assert.Equal(21, fourthValue); - Assert.Equal(1, stats.Data[EntryActionKind.Set]); - Assert.Equal(1, stats.Data[EntryActionKind.HitNormal]); - Assert.Equal(2, stats.Data[EntryActionKind.HitStale]); - Assert.Equal(1, stats.Data[EntryActionKind.FailSafeActivate]); + Assert.Equal(1, stats[EntryActionKind.Set]); + Assert.Equal(1, stats[EntryActionKind.HitNormal]); + Assert.Equal(2, stats[EntryActionKind.HitStale]); + Assert.Equal(1, stats[EntryActionKind.FailSafeActivate]); } } diff --git a/tests/ZiggyCreatures.FusionCache.Tests/Stuff/EntryActionsStats.cs b/tests/ZiggyCreatures.FusionCache.Tests/Stuff/EntryActionsStats.cs index 53f53d74..b47a4e7c 100644 --- a/tests/ZiggyCreatures.FusionCache.Tests/Stuff/EntryActionsStats.cs +++ b/tests/ZiggyCreatures.FusionCache.Tests/Stuff/EntryActionsStats.cs @@ -13,9 +13,17 @@ public EntryActionsStats() } } + public int this[EntryActionKind kind] => Data[kind]; + public int Total => Data.Values.Sum(); public ConcurrentDictionary Data { get; } public void RecordAction(EntryActionKind kind) { Data.AddOrUpdate(kind, 1, (_, x) => x + 1); } + + public void RecordActionIf(EntryActionKind kind, bool condition) + { + if (condition) + RecordAction(kind); + } }