CoreSystem.Cache.Rehydration
2.1.2
dotnet add package CoreSystem.Cache.Rehydration --version 2.1.2
NuGet\Install-Package CoreSystem.Cache.Rehydration -Version 2.1.2
<PackageReference Include="CoreSystem.Cache.Rehydration" Version="2.1.2" />
<PackageVersion Include="CoreSystem.Cache.Rehydration" Version="2.1.2" />
<PackageReference Include="CoreSystem.Cache.Rehydration" />
paket add CoreSystem.Cache.Rehydration --version 2.1.2
#r "nuget: CoreSystem.Cache.Rehydration, 2.1.2"
#:package CoreSystem.Cache.Rehydration@2.1.2
#addin nuget:?package=CoreSystem.Cache.Rehydration&version=2.1.2
#tool nuget:?package=CoreSystem.Cache.Rehydration&version=2.1.2
⚡ CoreSystem.Cache.Rehydration
Cache recovery component for CoreSystem.Cache on .NET 8
CoreSystem.Cache.Rehydration restores entries that were kept in the memory fallback after the primary cache provider becomes healthy again. It does not implement a cache provider: it reads tracked entries from the memory fallback and writes them to the current primary storage.
✨ Features
- ✅ Restores fallback entries into the primary storage after a recovery
- ✅ Recovery driven by
primary-tagged health checks, not by a timer alone - ✅ Preserves remaining expiration and tags when writing back
- ✅ Per-entry fault isolation: one failure never aborts the cycle
- ✅ Background service with a configurable interval
- ✅ Disabled by default when the core cache is disabled
📦 Installation
dotnet add package CoreSystem.Cache.Rehydration
This package requires an external primary storage. Install
CoreSystem.Cache.Redis, which registers Redis as that primary:
dotnet add package CoreSystem.Cache.Redis
| Package | Responsibility |
|---|---|
| CoreSystem.Cache | Cache orchestration, storage resolution and fallback support |
| CoreSystem.Cache.Rehydration | Recovery of tracked fallback entries into the primary storage |
🚀 Quick Start
Register the core cache and a primary provider first.
services.AddCoreCache(options =>
{
options.InstanceName = "my-app";
});
services.AddCoreCacheRedis(options =>
{
options.Configuration = redis =>
{
redis.EndPoints.Add("localhost", 6379);
};
});
services.AddHealthChecks();
Then register rehydration.
services.AddCoreCacheRehydration(options =>
{
options.Enabled = true;
options.Interval = TimeSpan.FromSeconds(30);
});
AddHealthChecks() is required. RehydrationService takes a
HealthCheckService in its constructor, and the background service is resolved
when the host starts. Without health checks registered, the host fails to start
with an InvalidOperationException.
Rehydration registration requires an enabled CoreSystem.Cache registration and
a registered external primary storage. IExternalCacheStorage is the internal
contract the provider registers that primary through; you do not implement it
yourself. If the core cache is disabled, the rehydration services are not
registered. If the primary storage is missing, registration throws an
InvalidOperationException.
🔄 How Recovery Works
Recovery applies to entries marked with CacheEntryOptions.Rehydrate. The
memory fallback tracks those keys.
Memory fallback
│
▼
Tracked cache keys
│
▼
MemoryRehydrationSource
│
▼
CacheRehydrator
│
▼
PrimaryRehydrationTarget
│
▼
ICacheStorageResolver.Primary
Each entry carries its key and value, and may also carry its remaining expiration and tags. Both are forwarded to the primary when available.
When an entry is stored successfully it is removed from the memory fallback. If storing it fails, the failure is logged, the entry stays in the fallback for a later cycle, and processing continues with the next entry. Expired or unavailable memory entries are skipped.
❤️ Primary Recovery Detection
Rehydration does not run merely because the primary is currently healthy. The
service inspects health checks tagged primary, and fires only after observing
the primary as unhealthy and then as healthy. If no primary-tagged check
exists, rehydration never triggers.
| Situation | Behaviour |
|---|---|
AddHealthChecks() was never called |
the host fails to start with an InvalidOperationException |
AddHealthChecks() was called but nothing is tagged primary |
no exception; the primary is treated as permanently unavailable and rehydration silently never runs |
With CoreSystem.Cache.Redis registered, the redis_cache check carries the
primary tag, so the second case only appears when rehydration is combined with
a provider that contributes no primary-tagged check.
After a successful cycle the component does not repeat while the primary stays healthy; a new recovery requires another unhealthy-to-healthy transition.
⚙️ Configuration
| Option | Default | Description |
|---|---|---|
Enabled |
true |
Enables registration of the rehydration services |
Interval |
30 seconds |
Delay used by the background rehydration service |
services.AddCoreCacheRehydration(options =>
{
options.Enabled = true;
options.Interval = TimeSpan.FromSeconds(30);
});
When Enabled is false, the options instance stays registered but the
rehydration source, target, rehydrator, service and hosted background service
are not.
🏗 Architecture
┌──────────────────────┐
│ IRehydrationSource │ reads tracked entries
│ (Memory fallback) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ ICacheRehydrator │ coordinates the transfer
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ IRehydrationTarget │ writes to the primary
└──────────────────────┘
RehydrationService drives the cycle from health-check transitions, and
RehydrationBackgroundService runs it on the configured interval. The
abstractions that separate source from target, like ICacheStorageResolver
behind them, are internal implementation boundaries; the package exposes no
public provider SDK for replacing either.
📚 Documentation
The full reference is published at federin.github.io/CoreSystem.Cache/Rehydration:
🤝 Contributing
Issues and pull requests are welcome. Build and test the full solution with
dotnet build CoreSystem.Cache.sln -c Release and
dotnet test CoreSystem.Cache.sln -c Release before opening a PR.
📄 License
Released under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- CoreSystem.Cache (>= 3.0.1)
- CoreSystem.Http (>= 1.1.0)
- CoreSystem.Memory (>= 1.0.3)
- CoreSystem.Resilience (>= 2.0.2)
- CoreSystem.Serialization (>= 1.2.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CoreSystem.Cache.Rehydration:
| Package | Downloads |
|---|---|
|
CoreSystem.Cache.Redis
Redis external cache provider for CoreSystem.Cache on .NET 8, with tag-based invalidation, distributed locking, health checks, and optional resilience integration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
3.0.1: Moves the dependency to CoreSystem.Cache 3.0.1, which depends on CoreSystem.Resilience 2.0.2. That combination is what restores this package on .NET SDK 10 and later: Resilience 2.0.1 pinned Microsoft.Extensions.* to 8.0.x while OpenTelemetry.Extensions.Hosting 1.19.0 asks for 10.0.0, and the resulting NU1605 broke restore before anything compiled. 3.0.0 cannot be fixed, because published versions are immutable. No public API changed, nothing was renamed, and no code changed here. The AddHealthChecks() prerequisite still applies: RehydrationService takes a HealthCheckService, so without it the host fails to start, and without a primary-tagged check rehydration silently never runs.