Skip to content

deps: Bump ZiggyCreatures.FusionCache.Serialization.SystemTextJson from 2.4.0 to 2.9.0 - #1

Merged
Lampjaw merged 1 commit into
mainfrom
dependabot/nuget/ZiggyCreatures.FusionCache.Serialization.SystemTextJson-2.9.0
Oct 5, 2026
Merged

Lampjaw merged 1 commit into
mainfrom
dependabot/nuget/ZiggyCreatures.FusionCache.Serialization.SystemTextJson-2.9.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 5, 2026

Copy link
Copy Markdown

Updated ZiggyCreatures.FusionCache.Serialization.SystemTextJson from 2.4.0 to 2.9.0.

Release notes

Sourced from ZiggyCreatures.FusionCache.Serialization.SystemTextJson's releases.

2.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:

  • backplane: when using an L1+L2 setup, a backplane is usually also used, and in that case the factory would not run because an update on L2 would be immediately visible to the other nodes
  • distributed locker: by using a distributed locker a factory would not run because nodes would coordinate so that only 1 factory runs concurrently, even on multiple nodes

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 async keyword 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 MemoryCache write fails (yep, it can happen, true story).

Here's an example of it:

  • a custom MemroyCache is being used as the L1
  • that instance has been configured with a SizeLimit
  • there's a cache miss
  • the factory executes successfully
  • the new entry does not have a Size specified
  • L1 write fails (because with a SizeLimit it's mandatory for every entry to specify a Size)

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-Safe

... (truncated)

2.8.0

🔒 Fix for distributed lock release when skipping L2 write

Community member @​joaopbnogueira spotted a problem with an edge case: when using SkipDistributedCacheWrite the 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 new RemoveByTag() call.
That was unfortunate, but it has now been fixed.

See here for the issue.

🏷️ Better handling of RemoveByTagBehavior.Remove

Community member @​gpetrou asked for some help regarding a certain scenario, and during the explanation/investigation it emerged that FusionCache could have handled RemoveByTagBehavior.Remove in 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.

2.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:

services.AddFusionCache()
  .WithDefaultEntryOptions(options =>
  {
    options.Duration = TimeSpan.FromSeconds(111);
  });

// LATER...

services.AddFusionCache()
  .WithDefaultEntryOptions(options =>
  {
    options.Duration = TimeSpan.FromSeconds(222);
  });

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:

  • multiple direct IFusionCache registrations (e.g.: multiple services.AddFusionCache() calls)
  • multiple named IFusionCache registrations (e.g.: multiple services.AddFusionCache(name) calls with the same name)
  • multiple keyed IFusionCache registrations (e.g.: multiple services.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 CacheKeyPrefix is now better, more limited in scope.
... (truncated)

2.7.1

[!NOTE]
You should update to v2.7.2, see here.

🏅 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 CacheKeyPrefix is now better, more limited in scope.

See here and here for the issues.

🆕 New SerializationConfigIssuesLogLevel option

See the previous item: with this new option is possible to change the desired log level, or suppress it.

🆕 New DistributedLockerErrorsLogLevel option

It'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 Activity is 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.

... (truncated)

2.7.0

[!NOTE]
You should update to v2.7.2, see here: there's a small issue in v2.7.0, nothing critical really, but better to use the new version.

🏅 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 CacheKeyPrefix is now better, more limited in scope.

See here and here for the issues.

🆕 New SerializationIssuesLogLevel option

See the previous item: with this new option is possible to change the desired log level, or suppress it.

🆕 New DistributedLockerErrorsLogLevel option

It'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 Activity is 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.

... (truncated)

2.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:

services.AddFusionCache()
	.WithOptions(options =>
	{
		options.RemoveByTagBehavior = RemoveByTagBehavior.Remove;
	});

See here for the original issue.

Ⓜ️ Add support for RemoveByTag("*") in HybridCache adapter

After 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.
... (truncated)

2.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:

Cache Stampede Request Coalescing

Such protection worked not just in the normal flow (miss -> factory -> return) but also with other more advanced features like:

  • Eager Refresh: hit (after the eager threshold) -> return + background factory
  • Factory Timeouts: miss -> factory + timeout -> return + background complete

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 StandardMemoryLocker is 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:

Distributed Cache Stampede, Before

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:

Distributed Cache Stampede, After

By providing an IFusionCacheDistributedLocker implementation during setup, FusionCache will take care of everything, we don't have to do anything else.

The setup looks like this:

services.AddFusionCache()
	// SERIALIZER
	.WithSerializer(
		new FusionCacheSystemTextJsonSerializer()
	)
	// DISTRIBUTED CACHE
	.WithDistributedCache(
		new RedisCache(new RedisCacheOptions
		{
			Configuration = "localhost:6379",
		})
	)
	// BACKPLANE
	.WithBackplane(
		new RedisBackplane(new RedisBackplaneOptions
 ... (truncated)

Commits viewable in [compare view](https://github.com/ZiggyCreatures/FusionCache/compare/v2.4.0...v2.9.0).
</details>

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ZiggyCreatures.FusionCache.Serialization.SystemTextJson&package-manager=nuget&previous-version=2.4.0&new-version=2.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

…om 2.4.0 to 2.9.0

---
updated-dependencies:
- dependency-name: ZiggyCreatures.FusionCache.Serialization.SystemTextJson
  dependency-version: 2.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github

dependabot Bot commented on behalf of github Oct 5, 2026

Copy link
Copy Markdown
Author

Labels

The following labels could not be found: dependencies. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@Lampjaw
Lampjaw merged commit 1f25f94 into main Oct 5, 2026
2 checks passed
@dependabot
dependabot Bot deleted the dependabot/nuget/ZiggyCreatures.FusionCache.Serialization.SystemTextJson-2.9.0 branch October 5, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant