Repository navigation
Conversation
Adds HybridCacheExtensions.GetAsync<T>, which reads L1 then L2 and reports whether a value was found, without invoking a factory or writing a miss to either tier. It is marked experimental (EXTEXP0018). DefaultHybridCache serves it through the existing stampede pipeline with DisableUnderlyingData, and a new IsDefaultResult marker on the shared stampede state lets every joined caller tell a miss apart from a cached default value. Other HybridCache implementations fall back to GetOrCreateAsync with both writes disabled. This also fixes a reference-count bug on the DisableUnderlyingData miss path: every joined caller was completed with one shared item that held a single reservation, so each extra caller over-released it (a Debug.Assert in debug builds, a drifting counter in release). The miss now completes with the stampede's own cache item, which already holds one reservation per caller. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
@dotnet-policy-service agree |
Collaborator
🎉 Good job! The coverage increased 🎉
Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1645965&view=codecoverage-tab |
Member
|
Marking as draft for now, see #5688 (comment). |
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.
Implements the API requested in #5688. The public API still needs API review on that issue before it can merge.
What it adds
HybridCacheExtensions.GetAsync<T>(key, options, cancellationToken)returnsValueTask<(bool Found, T? Value)>.EXTEXP0018, the existing HybridCache experiment ID). A constant for that ID is added toDiagnosticIds.Experiments.DefaultHybridCacheserves it through the existing stampede pipeline withDisableUnderlyingData:IsDefaultResultmarker on the sharedStampedeState<TState, T>lets every joined caller tell a miss apart from a cached0ornull.TStateas the statelessGetOrCreateAsyncoverload, so it can share work with those callers instead of throwing the wrong-type error.Other
HybridCacheimplementations fall back toGetOrCreateAsync, with both writes disabled and a factory that records the miss. The XML remarks document that fallback's limitation.Bug fix found along the way
On the
DisableUnderlyingDatamiss path,SetDefaultResultcompleted every joined caller withImmutableCacheItem<T>.GetReservedShared(). That shared item holds a single reservation, but each joined caller releases once when it unwraps the result. With N callers on one stampede, the item was released N times:Debug.Assert(newCount >= 0, "over-release detected");The miss now completes with the stampede's own cache item, set to
default. That item already holds one reservation per caller.GetReservedShared()has no other callers, so it is removed.JoinedGetOrCreateMissesWithoutUnderlyingDataBalanceReservationscovers this through the existingGetOrCreateAsyncAPI.Tests
GetAsyncTests(16 cases) covers:The full
Microsoft.Extensions.Caching.Hybrid.Testssuite passes on net8.0, net9.0 and net10.0 (macOS arm64). The API baseline was regenerated with ApiChief, with the existing assembly version line kept. The README gains a short usage example.🤖 Generated with Claude Code
Microsoft Reviewers: Open in CodeFlow