Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,21 @@ protected FusionCacheCommonEventsHub(IFusionCache cache, FusionCacheOptions opti
/// <summary>
/// The event for a cache set.
/// </summary>
/// <remarks>The event args has not been strongly typed to avoid breaking changes but it can be cast as an instance of <see cref="FusionCacheEntrySetEventArgs"/> when subscribed to.</remarks>
public event EventHandler<FusionCacheEntryEventArgs>? Set;

/// <summary>
/// The event for a cache remove.
/// </summary>
public event EventHandler<FusionCacheEntryEventArgs>? 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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, object?>(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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Caching.Memory;
using ZiggyCreatures.Caching.Fusion.Internals;

namespace ZiggyCreatures.Caching.Fusion.Events;

Expand All @@ -15,10 +16,23 @@ public class FusionCacheEntryEvictionEventArgs
/// <param name="reason">The reason for the eviction.</param>
/// <param name="value">The value being evicted from the cache.</param>
public FusionCacheEntryEvictionEventArgs(string key, EvictionReason reason, object? value)
: this(key, reason, value, null)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="FusionCacheEntryEvictionEventArgs"/> class.
/// </summary>
/// <param name="key">The cache key related to the event.</param>
/// <param name="reason">The reason for the eviction.</param>
/// <param name="value">The value being evicted from the cache.</param>
/// <param name="metadata">The metadata related to the cache entry evicted (if any).</param>
public FusionCacheEntryEvictionEventArgs(string key, EvictionReason reason, object? value, FusionCacheEntryMetadata? metadata)
: base(key)
{
Reason = reason;
Value = value;
Metadata = metadata;
}

/// <summary>
Expand All @@ -30,4 +44,9 @@ public FusionCacheEntryEvictionEventArgs(string key, EvictionReason reason, obje
/// The value being evicted from the cache.
/// </summary>
public object? Value { get; }

/// <summary>
/// The metadata related to the cache entry evicted (if any).
/// </summary>
public FusionCacheEntryMetadata? Metadata { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using ZiggyCreatures.Caching.Fusion.Internals;

namespace ZiggyCreatures.Caching.Fusion.Events;

/// <summary>
/// The specific <see cref="EventArgs"/> object for events related to cache entries' expirations.
/// </summary>
public class FusionCacheEntryExpirationEventArgs : FusionCacheEntryEventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="FusionCacheEntryExpirationEventArgs" /> class.
/// </summary>
/// <param name="key">The cache key related to the event.</param>
/// <param name="metadata">The metadata related to the cache entry expired (if any).</param>
public FusionCacheEntryExpirationEventArgs(string key, FusionCacheEntryMetadata? metadata)
: base(key)
{
Metadata = metadata;
}

/// <summary>
/// The metadata related to the cache entry expired (if any).
/// </summary>
public FusionCacheEntryMetadata? Metadata { get; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace ZiggyCreatures.Caching.Fusion.Events;
using ZiggyCreatures.Caching.Fusion.Internals;

namespace ZiggyCreatures.Caching.Fusion.Events;

/// <summary>
/// The specific <see cref="EventArgs"/> object for events related to cache entries' hits (eg: with a cache key and a stale flag).
Expand All @@ -11,13 +13,30 @@ public class FusionCacheEntryHitEventArgs : FusionCacheEntryEventArgs
/// <param name="key">The cache key related to the event.</param>
/// <param name="isStale">A flag that indicates if the cache hit was for a fresh or stale entry.</param>
public FusionCacheEntryHitEventArgs(string key, bool isStale)
: this(key, isStale, null)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="FusionCacheEntryHitEventArgs" /> class.
/// </summary>
/// <param name="key">The cache key related to the event.</param>
/// <param name="isStale">A flag that indicates if the cache hit was for a fresh or stale entry.</param>
/// <param name="metadata">The metadata related to the cache entry hit (if any).</param>
public FusionCacheEntryHitEventArgs(string key, bool isStale, FusionCacheEntryMetadata? metadata)
: base(key)
{
IsStale = isStale;
Metadata = metadata;
}

/// <summary>
/// A flag that indicates if the cache hit was for a fresh or stale entry.
/// </summary>
public bool IsStale { get; }

/// <summary>
/// The metadata related to the cache entry hit (if any).
/// </summary>
public FusionCacheEntryMetadata? Metadata { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using ZiggyCreatures.Caching.Fusion.Internals;

namespace ZiggyCreatures.Caching.Fusion.Events;

/// <summary>
/// The specific <see cref="EventArgs"/> object for events related to cache entries' set.
/// </summary>
public class FusionCacheEntrySetEventArgs : FusionCacheEntryEventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="FusionCacheEntrySetEventArgs" /> class.
/// </summary>
/// <param name="key">The cache key related to the event.</param>
/// <param name="metadata">The metadata related to the cache entry set (if any).</param>
public FusionCacheEntrySetEventArgs(string key, FusionCacheEntryMetadata? metadata)
: base(key)
{
Metadata = metadata;
}

/// <summary>
/// The metadata related to the cache entry set (if any).
/// </summary>
public FusionCacheEntryMetadata? Metadata { get; }
}
16 changes: 8 additions & 8 deletions src/ZiggyCreatures.FusionCache/Events/FusionCacheEventsHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public FusionCacheEventsHub(IFusionCache cache, FusionCacheOptions options, ILog
/// </summary>
public event EventHandler<EventArgs>? 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);
Expand All @@ -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<string, object?>(Tags.Names.OperationBackground, false));
Expand All @@ -130,15 +130,15 @@ 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<string, object?>(Tags.Names.OperationBackground, true));

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);
Expand Down Expand Up @@ -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<string, object?>(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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public FusionCacheMemoryEventsHub(IFusionCache cache, FusionCacheOptions options
/// <summary>
/// The event for a manual cache Expire() call.
/// </summary>
/// <remarks>The event args has not been strongly typed to avoid breaking changes but it can be cast as an instance of <see cref="FusionCacheEntryExpirationEventArgs"/> when subscribed to.</remarks>
public event EventHandler<FusionCacheEntryEventArgs>? Expire;

/// <summary>
Expand All @@ -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<string, object?>(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<string, object?>(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)
Expand All @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions src/ZiggyCreatures.FusionCache/FusionCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -536,8 +536,8 @@ private void CompleteBackgroundFactory<TValue>(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
Expand Down
3 changes: 2 additions & 1 deletion src/ZiggyCreatures.FusionCache/FusionCacheEntryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand Down
Loading