question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: The Cache DefaultAbsoluteExpireTime property work only once

See original GitHub issue

When upgrading to aspnet zero 11.2.1 (ABP 7.3.0) for .Net 6, the caching configuration in my module broke, because now cacheOptions.DefaultAbsoluteExpireTime is now a DateTimeOffset instead of a Timespan. ( #5422 )

I did the correction and tested it to verify if it was still working as expected, but I saw that after expiring, the cache wasn’t being used anymore. The new object was being fetched and stored, but the next call to the cache fetched the item again, instead of serving it from the cache.

I saw the changes in https://github.com/aspnetboilerplate/aspnetboilerplate/commit/51e3c9e1f7f5508905dd8931eba11fa501d0d633, and saw the reason: the set method stores the object with the already expired time.

See below how to reproduce:

Module.cs

public override void Initialize()
{
   IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

   this.Configuration.Caching.Configure("MyCache", cache =>
   {
      // 30sec to have it expire faster for test (I have it configured 15-30min usually)
      cache.DefaultAbsoluteExpireTime = DateTimeOffset.Now.AddSeconds(30);
   });
}

ClassService.cs

public async Task<IList<Model>> GetCachedDataAsync()
{
   IList<Model> list = await cacheManager
      .GetCache<string, List<Model>>("MyCache")
      .GetAsync(
         "MyCacheItem",
         async () =>
         {
            // after expiring the cache, every call to the GetCachedDataAsync method will hit here.
            return await this.classServiceRepository.GetAllAsync();
         });
   return list;
}

To not have a big impact in the existing calls, I created extension methods for the different cache stores used, where it’s in charge of storing the item with the proper absoluteExpireTime. Example:

public static async Task<TValue> GetFromMyCacheAsync<TKey, TValue>(this ITypedCache<TKey, TValue> cache, TKey key, Func<Task<TValue>> factory)
{
   TValue result = await cache.GetOrDefaultAsync(key);
   if (result == null)
   {
      result = await factory();
      cache.Set(key, result, absoluteExpireTime: DateTimeOffset.Now.AddMinutes(30));
   }

   return result;
}

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
malimingcommented, Jul 25, 2022

We can consider adding a factory method to get the AbsoluteExpireTime and its priority is greater than DefaultAbsoluteExpireTime.

DefaultAbsoluteExpireTimeFactory = _ => DateTimeOffset.Now + TimeSpan.FromSeconds(3);
1reaction
Omitalcommented, Oct 30, 2022

project and problem reproduction shared in issue https://github.com/aspnetboilerplate/aspnetboilerplate/issues/6577.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Releases · aspnetboilerplate/aspnetboilerplate
TargetNotifiers needs to be virtual in order for NHibernate to proxy it; ISSUE #6492: Bug: The Cache DefaultAbsoluteExpireTime property work only once ...
Read more >
Cache made consistent - Engineering at Meta
A static cache has a very simple cache model (e.g., a simplified CDN fits this model). Data is immutable. No cache invalidations. For...
Read more >
Application Data Caching
If several concurrent invocations try to retrieve a cache value from the same missing key, the method will only be invoked once.
Read more >
How To Implement Caching in Node.js Using Redis
The send method takes an object that has the following properties: fromCache : the property accepts a value that helps you know whether...
Read more >
Caching Best Practices | Amazon Web Services
The basic idea is to populate the cache only when an object is actually requested by the application. The overall application flow goes...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found