Skip to content

Conversation

@AndyButland
Copy link
Contributor

@AndyButland AndyButland commented Oct 19, 2025

Prerequisites

  • I have added steps to test this contribution in the description below

Addresses: #20537

Description

This PR makes two updates to resolve the linked issue;

  • Ensure we use a nullable type when checking for existence to align with retrieving from or creating in the cache. As were using a nullable type for one and not the other, this could explain why the hybrid cache sees misaligned types but reports them as the same.
  • Ensure we use the same overload for checking existence and retrieving from or creating in the cache. Possibly there's an issue here with the incorrect state object being applied meaning the types are considered different.

For background, this "exists" check was added in #19890 which was introduced to improve start up performance (allowing us to retrieve cached documents in batches from the database rather than one at a time).

I was able to reproduce the problem manually - it seemed to be consistent at least when using the Visual Studio template and IIS Express:

  • Create a new Umbraco project using 16.3.1.
  • Create a document type with a property, a template and a root content item.
  • Start Umbraco via Ctrl + F5 using IIS Express.
  • The reported error message could be seen.

The amends described above resolved the problem with the hybrid cache exception but revealed something else - that we would get an immediate page not found, and then after a refresh, the expected templated page would show. The crux of the problem here seemed to be that we are doing seeding on an application started notification, which doesn't seem correct. We should seed the initial content before we accept requests, and as such I've moved this to an application starting notification. That looks to resolve this problem.

There are some integration tests added in an attempt to replicate the problem. These didn't succeed in doing so, but are probably worth keeping anyway as additional testing around the hybrid cache.

Similarly there's some tightening up around the implementation of the "exists" check (the locking around "check and remove" and the cancellation token handling). None of this turned out to be the smoking gun, but I think they are valid improvements to consider keeping.

Testing

First try to replicate the problem consistently on main and then when you can, switch in the code from this PR and verify that the application starts without error and the expected initial page is shown.

…eval.

Ensure nullability of ContentCacheNode is consistent in exists and retrieval.
Copilot AI review requested due to automatic review settings October 19, 2025 21:30

This comment was marked as outdated.

@AndyButland AndyButland mentioned this pull request Oct 20, 2025
@AndyButland AndyButland requested a review from Copilot October 20, 2025 10:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Copy link
Contributor

@nikolajlauridsen nikolajlauridsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, and tests good to me too.

I was only able to reproduce by adding an actually redis cache, but then the issue also became very consistent, but this PR fixes it, great work 🎉

@nikolajlauridsen nikolajlauridsen merged commit 81a8a0c into main Oct 21, 2025
25 checks passed
@nikolajlauridsen nikolajlauridsen deleted the v16/bugfix/hybrid-cache-error branch October 21, 2025 07:57
nikolajlauridsen pushed a commit that referenced this pull request Oct 21, 2025
* Be consistent in use of GetOrCreateAsync overload in exists and retrieval.
Ensure nullability of ContentCacheNode is consistent in exists and retrieval.

* Applied suggestion from code review.

* Move seeding to Umbraco application starting rather than started, ensuring an initial request is served.

* Tighten up hybrid cache exists check with locking around check and remove, and use of cancellation token.

(cherry picked from commit 81a8a0c)
@nikolajlauridsen
Copy link
Contributor

Cherry picked to release/17.0 👍

AndyButland added a commit that referenced this pull request Oct 21, 2025
* Be consistent in use of GetOrCreateAsync overload in exists and retrieval.
Ensure nullability of ContentCacheNode is consistent in exists and retrieval.

* Applied suggestion from code review.

* Move seeding to Umbraco application starting rather than started, ensuring an initial request is served.

* Tighten up hybrid cache exists check with locking around check and remove, and use of cancellation token.
@AndyButland AndyButland changed the title Hybrid Cache: Resolve start-up errors with mis-matched types Hybrid Cache: Resolve start-up errors with mis-matched types (closes #20537) Oct 21, 2025
@umbracocommunity
Copy link

This pull request has been mentioned on Umbraco community forum. There might be relevant details there:

https://forum.umbraco.com/t/umbraco-upgrade-15-4-4-16-3-1-hybridcache-with-the-same-key/6363/4

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.

4 participants