ShouldEagerlyRefresh: System.InvalidOperationException: Nullable object must have a value #417
-
FusionCache: EagerExpirationTimestamp Becomes Null After Being CheckedIssue DescriptionWe have been using FusionCache for a while, and from time to time, we encounter the following exception:
From the error message, it is clear that the issue is related to Code AnalysisHere’s the FusionCache method where the exception is thrown:
According to the error log, ObservationsWe use EagerRefresh in two different places. Both trigger the error: 1. First place where cache is usedprivate readonly FusionCacheEntryOptions _slidingEntryOptions = new FusionCacheEntryOptions()
.SetDuration(TimeSpan.FromSeconds(60))
.SetFailSafe(true)
.SetFactoryTimeouts(TimeSpan.FromMilliseconds(50))
.SetEagerRefresh(0.8f);
public async Task<Dictionary<string, Result>> GetCached(string cacheKey, Func<CancellationToken, Task<IEnumerable<Result>>> factory, CancellationToken ct)
{
return await cache.GetOrSetAsync<Dictionary<string, Result>>(cacheKey,
async (context, token) =>
{
return await factory(ct);
}, _slidingEntryOptions, token: ct);
} 2. Second place where code is usedprivate readonly FusionCacheEntryOptions _slidingEntryOptions = new FusionCacheEntryOptions()
.SetDuration(TimeSpan.FromMinutes(5))
.SetFailSafe(true)
.SetFactoryTimeouts(TimeSpan.FromMilliseconds(100))
.SetEagerRefresh(0.8f);
public async Task<Result?> GetCached(VersionRulesCacheKey cacheKey, Func<string, CancellationToken, Task<Result?>> factory, CancellationToken ct)
{
return await cache.GetOrSetAsync<VersionRules?>(cacheKey, async (cancellationToken) =>
{
return await factory(cacheKey.VersionId, cancellationToken);
}, _slidingEntryOptions, token: ct);
} Questions
Any insights would be greatly appreciated! 🚀 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 6 replies
-
Hi @HannaHromenko , sorry for being late, it's been a busy and rough time lately.
Damn it, I think I know exactly why this is happening! I just created an issue to track this, already fixed it locally and will release it with v2.2.0 coming very soon. Thanks for spotting it! |
Beta Was this translation helpful? Give feedback.
Hi @HannaHromenko , sorry for being late, it's been a busy and rough time lately.
Damn it, I think I know exactly why this is happening!
Not so long ago I made a very small optimization regarding eager refresh, whereby once a cache entry enters a fail-safe cycle (after the first fail-safe activation) or even more frequently after an eager refresh kicks in (but before the entry expires), I now reset the eager refresh timestamp. This will reduce the amount of checks and tentative lock acquisition in high usage scenarios. But I did not consider all the edge cases around…