Repository navigation
[deps]: Update fusioncache monorepo to v2.9.0 - #6796
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
Collaborator
|
Internal tracking:
|
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
February 2, 2026 15:42
06fbefe to
474207c
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
February 12, 2026 12:15
474207c to
a5be458
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
2 times, most recently
from
February 24, 2026 14:21
a0a0e30 to
8253da3
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
March 13, 2026 13:39
8253da3 to
92488e2
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
March 21, 2026 10:38
92488e2 to
b7ae354
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
2 times, most recently
from
April 8, 2026 15:04
dfb4c5b to
913a95e
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
April 21, 2026 17:50
913a95e to
480bbd6
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
May 7, 2026 17:09
480bbd6 to
39e518f
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6796 +/- ##
=======================================
Coverage 74.83% 74.83%
=======================================
Files 2750 2750
Lines 117618 117618
Branches 10781 10781
=======================================
+ Hits 88022 88023 +1
+ Misses 26940 26939 -1
Partials 2656 2656 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
May 18, 2026 11:43
39e518f to
c34efdc
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
2 times, most recently
from
July 19, 2026 04:00
f4c8692 to
c252c8b
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
July 20, 2026 14:30
c252c8b to
19ed322
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
2 times, most recently
from
August 12, 2026 19:51
9a608a0 to
239768f
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
October 3, 2026 23:30
239768f to
32ff265
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
4 times, most recently
from
October 27, 2026 08:29
87d5fd4 to
a126ea5
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
November 2, 2026 19:00
a126ea5 to
46295ae
Compare
renovate
Bot
force-pushed
the
renovate/fusioncache-monorepo
branch
from
November 6, 2026 17:33
46295ae to
b95d487
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR body was truncated due to platform limits.
This PR contains the following updates:
[2.0.2]→[2.9.0][2.0.2]→[2.9.0][2.0.2]→[2.9.0]Release Notes
ZiggyCreatures/FusionCache (ZiggyCreatures.FusionCache)
v2.9.0🦅 Eager Refresh now also checks L2
Community member @sfhb24 noticed that during an Eager Refresh the L2 was not being checked.
Now, this is admittedly not a huge thing per se, because of 2 reasons:
In both these cases, the extra L2 check during an eager refresh would not be necessary.
Having said that, an L1+L2 setup without a backplane or a distributed locker may also be common, and in that case the new L2 check in the eager refresh window can in fact be helpful in reducing the amount of factory executions even more.
Long story short: I just implemented it!
See here for the issue.
🔒 Fix for memory locker + Eager Refresh edge case
If a factory fails when executed in the background during an eager refresh, FusionCache already takes care of everything and correctly releases the potentially acquired locks (memory and/or distributed), and this is good.
But community member @joaopbnogueira noticed a peculiar edge case: if the factory is not one marked with the
asynckeyword AND it throws an exception, the memory lock is not being released properly.Or, to better say, "was not". Because now this has been fixed.
Thanks João for spotting this.
See here for the issue.
🔒 Fix for distributed locker + skip L1 edge case
Community member @joaopbnogueira also noticed another peculiar scenario, specifically when a
MemoryCachewrite fails (yep, it can happen, true story).Here's an example of it:
MemroyCacheis being used as the L1SizeLimitSizespecifiedSizeLimitit's mandatory for every entry to specify aSize)In this scenario a distributed lock may not have been released.
But fear no more: this does not hapen anymore!
See here for the issue.
🧼 Fix for
Clear(false)+ Fail-SafeCommunity member @joaopbnogueira (damn, he is on a roll!) noticed something else, that somehow went unnoticed until now.
In some cases, after a
Clear(false)call, an expired entry saved with Fail-Safe enabled may still be returned by FusionCache.This too has now been fixed.
See here for the issue.
🔭 Allocation-free tags on the metrics hot path
Community member @GordeySt sent a PR with some really nice optimizations, particularly around reducing resource allocations and CPU consumption when working with metrics.
Now, even with metrics enabled, the hot path is allocation free.
That's great, thanks Gordey!
See here for the PR.
✅ Tests
The test suite just crossed the 1600 mark:
Nice 🙂
v2.8.0🔒 Fix for distributed lock release when skipping L2 write
Community member @joaopbnogueira spotted a problem with an edge case: when using
SkipDistributedCacheWritethe distributed locker was not being properly disposed, which was unfortunate.Now this has been fixed.
See here for the issue.
🏷️ Fix for tag marker re-materialization
Community member @igor-henriques noticed an issues because of which when the tag marker (the special cache entry containing the
RemoveByTag()timestamp) expired, it was being re-materialized with a newer timestamp: this could have led to the same results as a newRemoveByTag()call.That was unfortunate, but it has now been fixed.
See here for the issue.
🏷️ Better handling of
RemoveByTagBehavior.RemoveCommunity member @gpetrou asked for some help regarding a certain scenario, and during the explanation/investigation it emerged that FusionCache could have handled
RemoveByTagBehavior.Removein a slightly better way.It was mostly an edge case, but still: now the way it is internally handled is even better than before.
See here for the issue.
🔭 Better observability for user-initiated cancellations
Community member @dzmitry-tsarevich highlighted that user-initiated cancellations were being handled in a little-too-aggressive way from the oint of view of observability: too much background noise was being generated, which could lead to bloat.
Now this has been made better, slimmer.
See here for the issue.
👷 New builder ext methods
Community member @Stepami noticed the lack of a specific ext method on the builder to register the distributed locker based on Redis, basically
WithRedisDistributedLocker().After accepting his PR, I noticed a couple of extra ones were also missing, and so I added them.
See here for the issue.
Also, community member @petriceko asked for a new overload of the
WithOptions()ext method with better DI support: promptly, community member @vrbyjimmy made a PR to add that, which I merged.Talk about community collaboration 🙂
See here for the issue.
v2.7.2🔃 Better DI registrations checks
Community member @erikatsg noticed what seemed like a strange behavior, but after a preliminary check discovered that the problem was on their side, because they were adding the same FusionCache registration to the DI container more than once.
Something like this:
This is generally not suggested nor supported.
Luckily, FusionCache already had a series of checks for that and more strange situations, and those checks emit log records in those situations.
Unluckily though, those checks were previously performed only when asking to the DI container for an
IFusionCacheProvider(to work with named caches).Well, not anymore: now it works in any setup/scenarion, all automatically.
The current list of checks performed is:
IFusionCacheregistrations (e.g.: multipleservices.AddFusionCache()calls)IFusionCacheregistrations (e.g.: multipleservices.AddFusionCache(name)calls with the same name)IFusionCacheregistrations (e.g.: multipleservices.AddFusionCache().AsKeyedService(key)calls with the same key, for either named caches or the default cache)See here for the issue.
🏅 Better Advisor checks
A new check has been added in the Advisor that detecs a potentially incorrect configuration for a System.Text.Json based serializer related to value tuples.
This is not about a FusionCache bug, but about the System.Text.Json serializer's default configuration deviating from the commonly expected one (like, historically, Json.NET for example), see here for more.
Instead of forcing a specific json configuration for FusionCache, the Advisor now checks if the serializer in use is not supporting value tuples correctly and, if so, emits a warning (also configurable) in the logs to warn users about that.
This allows them to make the best decision for their specific use case.
Thanks to @sychare and @bassepeder for the hints.
Also, the check for a missing
CacheKeyPrefixis now better, more limited in scope.See here and here for the issues.
🆕 New
SerializationConfigIssuesLogLeveloptionSee the previous item: with this new option is possible to change the desired log level, or suppress it.
🆕 New
DistributedLockerErrorsLogLeveloptionIt's now possible to granularly configure the log level to use for distributed lockers errors, which is nice.
🔭 Better handling of OTEL parent traces
Sometimes the handling of OTEL parent traces was not the best, particularly around highly multithreaded scenarios where a native
Activityis not being passed around correctly in the context.This has now been fixed.
🏷️ OTEL traces for a
RemoveByTag(tag)operation now include the tag (duh)Normally, every operation in the cache has a cache key as the main argument.
In the case of a
RemoveByTag(tag)operation though, that is not the case since the main argument is not the cache key, but the tag: strangely enough, FusionCache previously was not logging it front and center, but now it does.This should help with tagging-related investigations and troubleshootings.
Thanks to community member @tvardero for spotting this.
See here for the issue.
🐞 Better temporal checks during an L2 to L1 copy
Thanks to community member @DanielStout5 for spotting this: it's quite rare, but sometimes an entry in L2 may be older than the corresponding entry in L1, and before this fix that assumption did not hold sometimes.
Now an extra check is performed, to make sure that this scenario doesnot produce unwanted results.
See here for the issue.
🐞 Missing operation id with tracing but without a logger
Every single operation in FusionCache has a uniquely identifying operation id (
OperationId): this becomes very useful with observability, mainly with logs.Previously, when no logger was present, the operation id was not generated, at all: this was an optimization to avoid useless work when not actually needed.
But in a case of traces being used without a logger, the traces did not include the operation id for the reason explain above.
With this fix, the optimization is still there, but it also takes into account trace listeners, so that when either a logger or a trace listener is present the operation id is generated, otherwise the optimization is still there.
🔒 Better exception handling for user-initiated cancellations with distributed locking
Community member @vrbyjimmy discovered a nasty issue with user-initiated cancellations when used with the distributed locker, see the issue for more details.
Than, community member @qjustfeelitp sent a PR to fix exactly this: teamwork doing its thing, amirite?
Long story short: now that specific OperationCanceledException is being specifically handled to avoid creating issues.
Thanks both!
See here for the issue.
Thanks to community member @SirPustekuchen for noticing that the MessagePack package version being normally used was since marked as vulnerable: now the reference has been updated.
And thanks to communiy membe @aki-matleb for doing the same, but for the OpenTelemetry.Api package.
See here and here for the issues.
📕 Docs
As always, I took some time to updated the docs with the latest stuff and make them overall better.
v2.7.1🏅 Better Advisor checks
A new check has been added in the Advisor that detecs a potentially incorrect configuration for a System.Text.Json based serializer related to value tuples.
This is not about a FusionCache bug, but about the System.Text.Json serializer's default configuration deviating from the commonly expected one (like, historically, Json.NET for example), see here for more.
Instead of forcing a specific json configuration for FusionCache, the Advisor now checks if the serializer in use is not supporting value tuples correctly and, if so, emits a warning (also configurable) in the logs to warn users about that.
This allows them to make the best decision for their specific use case.
Thanks to @sychare and @bassepeder for the hints.
Also, the check for a missing
CacheKeyPrefixis now better, more limited in scope.See here and here for the issues.
🆕 New
SerializationConfigIssuesLogLeveloptionSee the previous item: with this new option is possible to change the desired log level, or suppress it.
🆕 New
DistributedLockerErrorsLogLeveloptionIt's now possible to granularly configure the log level to use for distributed lockers errors, which is nice.
🔭 Better handling of OTEL parent traces
Sometimes the handling of OTEL parent traces was not the best, particularly around highly multithreaded scenarios where a native
Activityis not being passed around correctly in the context.This has now been fixed.
🏷️ OTEL traces for a
RemoveByTag(tag)operation now include the tag (duh)Normally, every operation in the cache has a cache key as the main argument.
In the case of a
RemoveByTag(tag)operation though, that is not the case since the main argument is not the cache key, but the tag: strangely enough, FusionCache previously was not logging it front and center, but now it does.This should help with tagging-related investigations and troubleshootings.
Thanks to community member @tvardero for spotting this.
See here for the issue.
🐞 Better temporal checks during an L2 to L1 copy
Thanks to community member @DanielStout5 for spotting this: it's quite rare, but sometimes an entry in L2 may be older than the corresponding entry in L1, and before this fix that assumption did not hold sometimes.
Now an extra check is performed, to make sure that this scenario doesnot produce unwanted results.
See here for the issue.
🐞 Missing operation id with tracing but without a logger
Every single operation in FusionCache has a uniquely identifying operation id (
OperationId): this becomes very useful with observability, mainly with logs.Previously, when no logger was present, the operation id was not generated, at all: this was an optimization to avoid useless work when not actually needed.
But in a case of traces being used without a logger, the traces did not include the operation id for the reason explain above.
With this fix, the optimization is still there, but it also takes into account trace listeners, so that when either a logger or a trace listener is present the operation id is generated, otherwise the optimization is still there.
🔒 Better exception handling for user-initiated cancellations with distributed locking
Community member @vrbyjimmy discovered a nasty issue with user-initiated cancellations when used with the distributed locker, see the issue for more details.
Than, community member @qjustfeelitp sent a PR to fix exactly this: teamwork doing its thing, amirite?
Long story short: now that specific OperationCanceledException is being specifically handled to avoid creating issues.
Thanks both!
See here for the issue.
Thanks to community member @SirPustekuchen for noticing that the MessagePack package version being normally used was since marked as vulnerable: now the reference has been updated.
And thanks to communiy membe @aki-matleb for doing the same, but for the OpenTelemetry.Api package.
See here and here for the issues.
📕 Docs
As always, I took some time to updated the docs with the latest stuff and make them overall better.
v2.7.0🏅 Better Advisor checks
A new check has been added in the Advisor that detecs a potentially incorrect configuration for a System.Text.Json based serializer related to value tuples.
This is not about a FusionCache bug, but about the System.Text.Json serializer's default behavior deviating from the commonly expected one (like, historically, Json.NET for example), see here for more.
Instead of forcing different json options specifically for FusionCache, the Advisor now checks if the serializer in use is not supporting value tuples correctly and, if so, emits a warning (also configurable) in the logs to warn users about that.
This allows them to make the best decision for their specific use case.
Thanks to @sychare and @bassepeder for the hints.
Also, the check for a missing
CacheKeyPrefixis now better, more limited in scope.See here and here for the issues.
🆕 New
SerializationIssuesLogLeveloptionSee the previous item: with this new option is possible to change the desired log level, or suppress it.
🆕 New
DistributedLockerErrorsLogLeveloptionIt's now possible to granularly configure the log level to use for distributed lockers errors, which is nice.
🔭 Better handling of OTEL parent traces
Sometimes the handling of OTEL parent traces was not the best, particularly around highly multithreaded scenarios where a native
Activityis not being passed around correctly in the context.This has now been fixed.
🏷️ OTEL traces for a
RemoveByTag(tag)operation now include the tag (duh)Normally, every operation in the cache has a cache key as the main argument.
In the case of a
RemoveByTag(tag)operation though, that is not the case since the main argument is not the cache key, but the tag: strangely enough, FusionCache previously was not logging it front and center, but now it does.This should help with tagging-related investigations and troubleshootings.
Thanks to community member @tvardero for spotting this.
See here for the issue.
🐞 Better temporal checks during an L2 to L1 copy
Thanks to community member @DanielStout5 for spotting this: it's quite rare, but sometimes an entry in L2 may be older than the corresponding entry in L1, and before this fix that assumption did not hold sometimes.
Now an extra check is performed, to make sure that this scenario doesnot produce unwanted results.
See here for the issue.
🐞 Missing operation id with tracing but without a logger
Every single operation in FusionCache has a uniquely identifying operation id (
OperationId): this becomes very useful with observability, mainly with logs.Previously, when no logger was present, the operation id was not generated, at all: this was an optimization to avoid useless work when not actually needed.
But in a case of traces being used without a logger, the traces did not include the operation id for the reason explain above.
With this fix, the optimization is still there, but it also takes into account trace listeners, so that when either a logger or a trace listener is present the operation id is generated, otherwise the optimization is still there.
🔒 Better exception handling for user-initiated cancellations with distributed locking
Community member @vrbyjimmy discovered a nasty issue with user-initiated cancellations when used with the distributed locker, see the issue for more details.
Than, community member @qjustfeelitp sent a PR to fix exactly this: teamwork doing its thing, amirite?
Long story short: now that specific OperationCanceledException is being specifically handled to avoid creating issues.
Thanks both!
See here for the issue.
Thanks to community member @SirPustekuchen for noticing that the MessagePack package version being normally used was since marked as vulnerable: now the reference has been updated.
And thanks to communiy membe @aki-matleb for doing the same, but for the OpenTelemetry.Api package.
See here and here for the issues.
📕 Docs
As always, I took some time to updated the docs with the latest stuff and make them overall better.
v2.6.0🏷️ Configurable cleanup behavior for
RemoveByTag()Normally, when calling
RemoveByTag("my-tag"), the entries with such a tag will be gradually expired on a subsequent access.Community member @charlesvigneault asked for the ability to instead properly remove them.
So I added a new option to allow configuring this behavior:
See here for the original issue.
RemoveByTag("*")in HybridCache adapterAfter the initial release of HybridCache in 2025, the team added support for a special case: using
RemoveByTag("*")to clear the entire cache.I didn't notice untile recently, and thanks to community user @vrbyjimmy I did that.
Or, to better say it, he did that!
He acted so quickly that a PR immediately landed with the implementation, so thanks Jakub for that!
What happens underneath is that a
RemoveByTag("*")call on the adapter is detected and re-routed to a Clear() call on the underlying FusionCache instance: very simple and elegant, and I like that a lot.See here for the original issue.
🔒 Better Distributed Locker + Eager Refresh
Community user @jgshowpad noticed that when using the new distributed stampede protection introduced in v2.5.0 with Eager Refresh some errors were being logged.
That was caused by the Redis-based distributed locker not handling correctly a timeout of zero (which btw is a pretty common approach to basically check for a lock already being acquired by someone else, without having to wait).
This has now been fixed.
See here for the original issue.
⚡ Perf boost for
GenerateOperationId()Community user @Inok contributed with a nice set of low-level perf optimizations for the
GenerateOperationId()internal method, which may be called quite a lot when doing observability (logging, OTEL, etc).That's a very nice and welcome contribution, thanks Pavel!
See here for the original issue.
🔒 Add missing ext method for DI registration of
Community member @mumin-khan noticed that, after releasing distributed stampede support in v2.5.0, I missed the related ext method for the the DI registration.
So now I added it, and it's now possible to do this:
This has now been added, thanks Mumin!
See here for the original issue.
🐞 Fixed a couple of missing
ConfigureAwait(false)Community user @JerinMathewJose01 noticed that on the old .NET Framework 4.7.2 and 4.8, sometimes the factory may remain stuck without completing correctly.
That was caused by a couple of missing
ConfigureAwait(false)when awaiting the factory execution.This has now been fixed.
See here for the original issue.
📕 Docs
As always, I took some time to updated the docs with the latest stuff and make them overall better.
v2.5.0🛡️ Distributed Cache Stampede Protection
Since the very beginning FusionCache offered a solid Cache Stampede protection, as explained in the docs where it is clearly illustrated:
Such protection worked not just in the normal flow (miss -> factory -> return) but also with other more advanced features like:
With time the stampede protection got even better, and even extensible: this allowed 3rd party implementations of the core mechanism, called memory locker (
IFusionCacheMemoryLocker).All of this without removing the normal "it just works" experience since, by default, a
StandardMemoryLockeris used without needing any user setup or intervention.Cool.
But here's the thing: this protection had always been a local thing, meaning it did not span multiple nodes, in a distributed way: this meant that, if we were "unlucky", multiple factories could have run at the same time for the same cache key on different nodes.
Meaning, this:
But that was true until now: enter Distributed Cache Stampede Protection 🎉
Thanks to the introduction of the new
IFusionCacheDistributedLocker(see the next point) it's now possible to coordinate factory execution accross multiple nodes, so that only one factory would run at the same time for the same cache key even on different nodes.Meaning, this:
By providing an
IFusionCacheDistributedLockerimplementation during setup, FusionCache will take care of everything, we don't have to do anything else.The setup looks like this:
Or, even better, if we want to re-use the same connection multiplexer for better performanceand use of resources, we can do this:
As always, the idea is that "it just works".
See here for the original issue.
🔒 Extensible Distributed Locking
As mentioned above, this is the new distributed component responsible for coordinating multiple factory executions on different nodes, all automatically.
As of now I'm providing 2 main implementations:
Of course the Redis one is the only real deal for now, meant for production use.
Other implementations in the future will be possible, by simply implementing the new
IFusionCacheDistributedLockerabstraction, just like it was possible before with theIFusionCacheMemoryLockerabstraction.So to recap:
I would say it's all pretty nice 🙂
See here for the original issue.
⚙️ New
MemoryCacheDurationentry optionThis is seemingly small, but really important.
In a multi-node scenario with an L1+L2 setup it's important to keep the cache, as a whole, coherent.
When using a Backplane there's no need to do anything: all is taken care of, and the cache as a whole is always coherent.
But wha if we cannot or don't want to use a backplane, for... reasons?
Well, every change in the cache will leave the other L1s out-of-sync for the remaining time before their expiration, and this is not good.
This problem is known as Cache Coherence, and the backplane is what is used to SOLVE it.
But if we can't use a backplane, we should at least MITIGATE it: and we can do that by reducing the incoherency window.
And how?
Well, by simply specifying 2 different durations: one for the L1 and one for the L2.
Now, with FusionCache it has always been possible to specify a different
Durationfor the distributed cache, thanks to theDistributedCacheDurationoption.The problem was that, when in the scenario above (L1+L2 and no backplane), it would have been nice to be able to simply say "keep all the durations as alrady specified, and just refresh the data in the L1 from L2 every few seconds".
But with only the
DistributedCacheDurationoption available, the way to achieve this was counterintuitive: instead of somehow override the L1 duration, we needed to lower the normalDurationto a few seconds and specify the intended logical duration as theDistributedCacheDuration.Not terrible, but not great.
But now, not anymore: enter
MemoryCacheDuration.We can of course go granular on a call-by-call basis, but there's something better: we can simply specify a value in the
DefaultEntryOptions, and all the existing call sites will inherit this new value which will automatically override the duration only for the L1.Done.
And, if we use Tagging we can simply do the same thing for the
TagsDefaultEntryOptions, and we're done.Something like this:
Oh, and the new Best Practices Advisor (see next point) can already give this advice when it detects such a scenario.
Nice 🙂
See here for the original issue.
🏅 Best Practices Advisor
Sometimes we may inadvertently fall into a scenario with:
With time FusionCache got more and more new components (like #575 ) and options (like #571 ) and this, along with the naturally dynamic nature of a flexible setup and configuration, may lead to inadvertently make the wrong decisions and fall into some gotchas.
FusionCache already had a couple of internal checks, like looking for a missing
CacheKeyPrefixwhen using a shared L1 (which may lead to cache key collisions), and warns about them in the logs.Now this practice has been unified & expanded, and it has a name: Best Practices Advisor.
Long story short, FusionCache now checks for common pitfalls and can give warnings and suggestions, all automatically and based on the current runtime state: no need to scrape the docs to see if the current config may lead to surprises thanks to a bad incantation of options.
I'd like to highlight that I've been careful about not trying to make it too smart for its own good: that is an easy to miss cliff that would lead to exaggerate in the implemented heuristics and checks, leading to bad results.
The checks initially implemented are:
More checks will be added in the future, but for now these are already quite useful.
Oh, one final thing: if you are thinking "great, a new piece of AI crap that will waste resources" then... nah, it's just a bunch of
ifs done automatically in the background during startup. And if you want you can disable the Advisor by simply setting the newEnableBestPracticesAdvisoroption tofalse(default istrue).See here for the original issue.
⚙️ New
IgnoreTimeoutsWhenDebuggingoptionCommunity user @tvardero asked if it was possible to automatically ignore all timeouts when debugging.
That was in fact an interesting feature request, and after some investigations I decided to proceed.
Now, when setting the new
IgnoreTimeoutsWhenDebuggingoption totrue, all timeouts will be ignored, but ONLY when there is a debugger attached (viaDebugger.IsAttached).All in all this will help when debugging issues locally, without nasty timeouts hitting simply because we are inspecting a variable after a breapoint hit, which is... the whole point of debugging, right?
Thanks @tvardero for the input!
See here for the original issue.
See here for the feature design issue.
🕑 Small timestamps change
Thanks to community user @vit-svoboda I changed the logic that gets the timestamp for a new entry, generated from a factory.
Before, the timestamp was about the moment the factory ended, now it's when it started.
No big change really, but it should help in a couple of edge cases with high concurrency.
See here for the original issue.
⚡ Minor performance tweaks
Nothing big really, as the perf were already great: just a bunch of extra tuning in a couple of edge cases, nothing big really.
📕 Docs (not yet!)
I did not have time to update the docs related to all this new stuff, but I'll do it in the next few days, pinky promise.
For now, this massive release note should be good enough.
✅ Tests
As always, with new features come new tests to make sure that all work as intended, now and in the future (regressions, am I right?).
Now we're up to 1534 total running tests, including params combinations & friends.
I can always do more, but still: not bad.
v2.4.0🏷️ Add
StaleTagsto factory execution contextCommunity user @ted-mundy noticed a tricky behavior when using Tagging with stale entries (see next point).
To solve it, I added a new
StaleTagsproperty to the factory execution context, so that now it's possible to access both the tags that are being passed to theGetOrSet()call and the existing tags of the stale entry in the cache (if any), like this:This can be useful even in other scenarios, like applying some custom logic about what to do based on the tags already in the cache.
Nice.
🐞 Fix for tags with stale entries
As mentioned above, community user @ted-mundy noticed a tricky behavior when using Tagging with stale entries.
Thanks to the addition of the new
StaleTagsproperty, this is now solved for good.Thanks @ted-mundy !
See here for the original issue.
Community user @TheSpookyElectric noticed that, when working with the HybridCache adapter, the
LocalCacheExpirationwas not being handled correctly in all cases.The mapping logic has been updated to account for that, and it now works as expected.
Thanks @TheSpookyElectric !
See here for the original issue.
🐞 Fix for
WithRegisteredSerializer()Community user @Inok noticed something... strange.
The builder, when calling
WithRegisteredSerializer()on it, was doing something else: acting on the distributed cache.That was, well... dumb, that's just what it was: my bad.
Now this has been solved.
Thanks @Inok !
See here for the original issue.
🐞 Fix for
InvalidOperationExceptionwhen usingAlwaysOffSamplerwith OTELCommunity user @DFSko noticed an
InvalidOperationExceptionbeing thrown when working with OTEL and using theAlwaysOffSampler: this had to do with setting the currentActivityafter certain operations, in conjunction with activities with a state not compatible for being set as the current one.This has now been solved.
Thanks @DFSko !
See here for the original issue.
📕 Fix for an inline doc issue
Community user @marcominerva discovered a wrong description for the
WithDistributedCache()method on the builder: fixed.Thanks @marcominerva !
See here for the original issue.
✅ 1500 tests, huzza!
FusionCache reached 1500 tests:
That's it, that's the tweet 🙂
v2.3.0🔑 Access the cache key in the factory context
Community user @posledam and others asked for the ability to access the cache key in the factory context, to be able to work with it while going to the database or similar, without creating a closure with the lambda.
So that's what I added, but there's a catch here: FusionCache provides automatic cache key manipulation with things like
CacheKeyPrefixusually in conjunction with things like Named Caches, so it would be nice to access both the original one and the processed one.Therefore I added both of them in the factory context, and it can be used like this:
See here for the original issue, and here for the design issue.
⚙️ New
InternalStringsoptionsFusionCache automatically handles a lot of things for us, and to do that it may need to manipulate some strings used internally like the cache key or the backplane channel name.
For example to use the
CacheNameto automatically separate data in a shared cache when used in conjunction with other FusionCache instances, or the set of special cache keys used with Tagging or the way [wire format versioning]Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR was generated by Mend Renovate. View the repository job log.