Closed sabbadino closed 6 months ago
Hi @sabbadino , I would suggest not to try and mix together different features and scenarios, let's try to tackle each part by itself.
Basically all methods in FusionCache that act on cache entries require some options per each entry, called entry options.
Whether you specify them or not, they are there (this is important).
It is possible to define a "global" DefaultEntryOptions
, which act as a default value in case that's needed.
While calling each method you can specify them in different ways:
FusionCacheEntryOptions
instanceDefaultEntryOptions
will be usedDefaultEntryOptions
(which will be duplicated for you by FusionCache) and then make some changes, tyically via a fluent api (eg: opt.SetDuration(...).SetFailSafe(...)
etc)Basically the DefaultEntryOptions
are used either when you call a method and don't specify anything, or as a "starting point" for when using the lambda (eg: opt => opt.SetDuration(...)
etc).
Even when using Adaptive Caching (via a normal GetOrSet
call) some entry options are used anyway by one onf the above ways (eg: if you don't pass anything the DefaultEntryOptions
will be used, etc): these options are the ones you'll find inside the FusionCacheFactoryExecutionContext
object in the Options
property.
Now, when inside of the factory you can either change some properties on the FusionCacheFactoryExecutionContext.Options
property like this:
// INSIDE THE FACTORY
ctx.Options.Duration = TimeSpan.FromSeconds(10);
or even completely overwrite it, like this:
// INSIDE THE FACTORY
ctx.Options = new FusionCacheEntryOptions() {
// ...
};
In case you need it, there's a Duplicate()
method on the FusionCacheEntryOptions
object that, well, duplicate it to a new one (and, spoiler, it's the one used internally by FusionCache when using the lambda opt => opt
etc).
You may be thinking that when changing some options with Adaptive Caching, you may be inadvertently changing the original options or the DefaultEntryOptions
(eg: if you haven't passed anything), thereby breaking something: but don't worry because FusionCache will protect you from this by automatically duplicating the entry options behind the scenes to avoid changing a shared options object.
Also, it will do this both automatically (no manual intervention needed) and in an optimized way, meaning it will do that only when you are actually trying to modify something that was not marked as being "modifiable".
So, to recap:
Duplicate()
to get a copy of an existing entry options object, ready to be modified without altering the original oneLet me know if you need more.
Hope this helps.
I'll add:
I understand that I can change the properties of the "global" FusionCacheEntryOptions in
Action<FusionCacheEntryOptions>
Not 100%: as said, you'll be changing a copy of the "global" ones, not directly them, so everything is safe.
In my scenario I have a specific set of values for FusionCacheEntryOptions that I want to apply in the
Action<FusionCacheEntryOptions>
. Since it's an Action I cannot replace the provided FusionCacheEntryOptions .
Why can't you pass them directly when calling the method?
Do I need to copy manually the settings or there is something like a FusionCacheEntryOptions (instance) .CopyFrom method I can call in the Action ? Something like
var ret = await _fusionCache.GetOrSetAsync<T>(key, factory, opt => { opt.CopyFrom(myOpt); });
Just do:
var ret = await _fusionCache.GetOrSetAsync<T>(key, factory, myOpt);
Or am I missing something?
Hi, sorry my fault, I did a mistake when looking at overloads of GetOrSetAsync taking
Func<FusionCacheFactoryExecutionContext<TValue>, CancellationToken, Task<TValue>> factory
I missed the one taking a FusionCacheEntryOptions .. I only saw the ones taking an
Action<FusionCacheEntryOptions>
that's was the reason why I opend the 'Issue' ..
sorry wasting your time :)
Enrico
No worries!
Can the docs be updated for this? I ran into the same issue since the full options object was what intellisense picked and spent some time figuring out why failback stopped working with my global defaults. The Step by Step directions have a code sample though don't explicitly call out the two ways and none of the built in logging mentions overriding the defaults either in a way to preserve the global defaults.
Can the docs be updated for this?
Good idea!
To be clear you mean a more detailed explanation of the whole defaults -> customization via lamba thing, so that defaults are preserved, right?
Something to make it more obvious at first pass that you're not setting a single override.
Example from the Step by Step
We can do this very easily, either by specifying it per-call, maybe using the available fluent api, like this:
var product = _cache.GetOrSet<Product>(
$"product:{id}",
_ => GetProductFromDb(id),
options => options.SetFailSafe(true, TimeSpan.FromHours(2), TimeSpan.FromSeconds(30))
);
or, as before, by setting the DefaultEntryOptions
object during the registration:
services.AddFusionCache()
.WithDefaultEntryOptions(new FusionCacheEntryOptions {
Duration = TimeSpan.FromMinutes(1),
// FAIL-SAFE OPTIONS
IsFailSafeEnabled = true,
FailSafeMaxDuration = TimeSpan.FromHours(2),
FailSafeThrottleDuration = TimeSpan.FromSeconds(30)
})
;
or, pass in a FusionCacheEntryOptions
to override all defaults per-call
var product = _cache.GetOrSet<Product>(
$"product:{id}",
_ => GetProductFromDb(id),
new FusionCacheEntryOptions {
// OVERRIDE DEFAULTS
Duration = TimeSpan.FromSeconds(30),
IsFailSafeEnabled = false,
})
;
Hi all, I just updated the Options docs: looks clearer now?
Problem
I am playing with adaptive caching. Looking at the code in this page https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/AdaptiveCaching.md I understand that i can set Duration in the Factory body I understand that if i don't set duration and other properties in the factory the "global" FusionCacheEntryOptions is used. I understand that I can change the properties of the "global" FusionCacheEntryOptions in
Action<FusionCacheEntryOptions>
In my scenario I have a specific set of values for FusionCacheEntryOptions that I want to apply in the
Action<FusionCacheEntryOptions>
. Since it's an Action I cannot replace the provided FusionCacheEntryOptions .Do I need to copy manually the settings or there is something like a FusionCacheEntryOptions (instance) .CopyFrom method I can call in the Action ? Something like
Or anyway, how can use a "custom" FusionCacheEntryOptions in adaptive sampling , and not the global one ? All overloads that takes a FusionCacheFactoryExecutionContext accepts a Action and not simply options
thanks Enrico