Skip to content

fix(cache): resolve CacheOptions from DI so multi-call AddCache merges#45

Merged
poxet merged 1 commit into
masterfrom
feature/fix-addcache-options-capture
May 11, 2026
Merged

fix(cache): resolve CacheOptions from DI so multi-call AddCache merges#45
poxet merged 1 commit into
masterfrom
feature/fix-addcache-options-capture

Conversation

@poxet
Copy link
Copy Markdown
Contributor

@poxet poxet commented May 11, 2026

Summary

AddCache singletons used to close over the local CacheOptions o, so when AddCache was called twice (e.g. an app calling it directly and transitively via AddQuilt4NetApplicationInsightsClient), the second call's RegisterType<> registrations were silently dropped. The existing AppendPreviousRegistrations helper + RemoveAll<IOptions<CacheOptions>> + re-add pattern clearly intended to support multi-call composition — only the singleton-options binding was broken.

The 6 affected factories (IFetchQueue, IManagedCacheMonitor, IEternalCache, ITimeToLiveCache, ITimeToIdleCache, IScopeCache) now resolve IOptions<CacheOptions>.Value from the service provider at first resolution, so they see the merged options from the last AddCache call.

  • Reported by Eplicta (2026-04-14): 23 production InvalidOperationException: "No freshSpan provided and no DefaultFreshSpan configured for cache type EnvironmentOption[]" from TimeCacheBase.GetDefaultFreshSpan<T>() — the type was registered, just not in the o the first call's closure had captured.
  • First-call-wins on type registrations preserved (AppendPreviousRegistrations uses TryAdd).
  • Scope expanded from the 4 caches Eplicta listed to all 6 factories — IFetchQueue and IManagedCacheMonitor had the same bug.
  • Version bump Tharga.Cache 1.0.0 → 1.1.0.

Test plan

  • Regression test AddCache_CalledTwice_SecondCallRegistrationHonoredAtRuntime added to AddCacheIdempotencyTests — confirmed it fails on master with the exact Eplicta exception, then passes with the fix
  • dotnet test Tharga.Cache.Tests — 474/474 pass
  • dotnet test Tharga.Cache.Redis.Tests — 2/2 pass
  • dotnet build -c Release — green
  • CI green on this PR
  • Once merged + released: Eplicta bumps Tharga.Cache to 1.1.0 and removes the workaround in Core/Eplicta.Aggregator/Program.cs (follow-up to be tracked in Requests.md)

Singletons in AddCache used to close over the local CacheOptions `o`,
so a second AddCache call's RegisterType<> registrations were silently
ignored even though AppendPreviousRegistrations + RemoveAll<IOptions>
clearly intended to support multi-call composition.

Now every factory (IFetchQueue, IManagedCacheMonitor, IEternalCache,
ITimeToLiveCache, ITimeToIdleCache, IScopeCache) resolves
IOptions<CacheOptions>.Value from the service provider, so the last
call's merged options are honored at first resolution.

Reported by Eplicta 2026-04-14 (23 production exceptions from
"No freshSpan provided and no DefaultFreshSpan configured for cache
type EnvironmentOption[]"). Bumps Tharga.Cache 1.0.0 -> 1.1.0.

Regression test added in AddCacheIdempotencyTests.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 11, 2026

Codecov Report

❌ Patch coverage is 28.57143% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
Tharga.Cache.Tests/AddCacheIdempotencyTests.cs 0.00% 9 Missing ⚠️
Tharga.Cache/CacheRegistrationExtensions.cs 50.00% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

@poxet poxet merged commit 5842fbb into master May 11, 2026
3 of 5 checks passed
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