extensions icon indicating copy to clipboard operation
extensions copied to clipboard

HybridCache: Enable setting expiration based on value in factory

Open lindeberg opened this issue 1 year ago • 11 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

My HybridCache factory is fetching data from an HTTP API. The fetch response includes a maxAge header, from which I want to set cache expiration.

There's no way of getting the value from the factory method to the expiration setting.

Describe the solution you'd like

Some way to enable this

Additional context

No response

lindeberg avatar Jun 27 '24 13:06 lindeberg

we also need such feature. maybe change "HybridCacheEntryOptions? options" in method signature to "Func<T, HybridCacheEntryOptions?>" ?

Gutse avatar Aug 06 '24 12:08 Gutse

This should not be "hard" to do but brings a lot of value since one can set expiration depending on the factory response.

xnf avatar Nov 21 '24 10:11 xnf

Hi, folks. I am just highlighting that it was also requested in the discussions/forum here: https://github.com/dotnet/aspnetcore/discussions/57021

wilsonneto-swe avatar Dec 08 '24 15:12 wilsonneto-swe

The demand is noted. We can try to look at what we can add here.

mgravell avatar Dec 08 '24 16:12 mgravell

Without this feature we have to continue with our MemoryCache and IDistirbutedCache combination

palcarlsen avatar Mar 13 '25 09:03 palcarlsen

@palcarlsen if you have this specific need, you can meanwhile use FusionCache, which supports this in the form of adaptive caching.

You can use it now directly and in the future, if you want, switch to use the HybridCache adapter and then, again if desired, change the implementation to the Microsoft one when this feature may become available.

Hope this helps.

jodydonetti avatar Mar 13 '25 09:03 jodydonetti

Any update on when this can be expected to be available? I rather use the abstract that HybridCache gives (which I expected to support this already cause IMemoryCache does also) instead of using FusionCache (how amazing it may be)

ThaDaVos avatar Jul 25 '25 11:07 ThaDaVos

(if someone could unassign me, that'd be awesome, thx)

mgravell avatar Jul 25 '25 12:07 mgravell

Done all the ones I have permissions to do so on.

martincostello avatar Jul 25 '25 12:07 martincostello

@lindeberg For the time being have you tried using something like this?

var data = await _hybridCache.GetOrCreateAsync(key, _ => ValueTask.FromResult(""), new HybridCacheEntryOptions { Flags = HybridCacheEntryFlags.DisableUnderlyingData }); // Does not call the factory so it will return null if not found in cache

// Some logic to assign a value to data

_hybridCache.SetAsync(key, data, new HybridCacheEntryOptions
{
    Expiration = CalculateExpiration(data) // your logic to calculate the expiration.
}).GetAwaiter().GetResult();

Not the cleanest solution, but you can probably create a version of GetOrCreateAsync to hide this from the rest of the code.

endizhupani-cel avatar Sep 16 '25 14:09 endizhupani-cel

It's not possible @endizhupani-cel , for a couple of reasons:

  • null is a perfectly valid value, and can be the value in the cache (it's also a best practice to cache nulls) and by checking for it you are handling a cache hit with null as a cache miss
  • by using 2 separate method calls you are losing stampede protection

I also tried multiple ways to achieve with HybridCache what in FusionCache is adaptive caching, but I got to 4 min barriers:

  • each option in HybridCacheEntryOptions is init-only
  • the entire HybridCacheEntryOptions class is sealed
  • the signature for the factory does not allow changing it
  • even by being able to change an existing instance somehow (eg: reflection etc), I think something internally would break because the implementation counts on those instances to be readonly (e.g.: look here)

Hope this helps.

jodydonetti avatar Sep 16 '25 15:09 jodydonetti

Is there any update on when this will be available? Thank you

MarGraz avatar Dec 18 '25 16:12 MarGraz