Hellnet.Cache
1.1.10
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package Hellnet.Cache --version 1.1.10
NuGet\Install-Package Hellnet.Cache -Version 1.1.10
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Hellnet.Cache" Version="1.1.10" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Hellnet.Cache" Version="1.1.10" />
<PackageReference Include="Hellnet.Cache" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Hellnet.Cache --version 1.1.10
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Hellnet.Cache, 1.1.10"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Hellnet.Cache@1.1.10
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Hellnet.Cache&version=1.1.10
#tool nuget:?package=Hellnet.Cache&version=1.1.10
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Hellnet.Cache
Multi-layer cache library for .NET with L1 (memory), L2 (Valkey/Redis), and optional External cache provider. Write-through, read-through, stampede-protected, env-first configuration.
Layers
| Layer | Provider | TTL default | Resilient |
|---|---|---|---|
| L1 | MemoryCacheProvider (in-process) |
5 min | Always healthy |
| L2 | ValkeyCacheProvider (StackExchange.Redis) |
30 min | Graceful degradation on miss |
| L3 | ExternalCacheProvider (pluggable, opt-in) |
15 min | Disabled by default |
Quick start
dotnet add package Hellnet.Cache
using Hellnet.Cache;
// ── Env-first (recommended) ────────────────────────────
// Throws if HELLNET_CACHE_VALKEY_CONNECTION or
// HELLNET_CACHE_VALKEY_PASSWORD are missing.
builder.Services.AddHellnetCache();
// ── Explicit — no validation ───────────────────────────
// You are responsible for providing valid values.
builder.Services.AddHellnetCache(new HellnetCacheOptions
{
ValkeyConnection = "valkey.hellnet.com.br:6379",
ValkeyPassword = "hellnet2026",
});
Minimal env config (env-first)
# Required — without these, AddHellnetCache() throws at startup
export HELLNET_CACHE_VALKEY_CONNECTION=valkey.hellnet.com.br:6379
export HELLNET_CACHE_VALKEY_PASSWORD=hellnet2026
Se esquecer de setar, o erro é claro:
Hellnet.Cache: AddHellnetCache() failed — required environment variables are missing:
❌ HELLNET_CACHE_VALKEY_CONNECTION
❌ HELLNET_CACHE_VALKEY_PASSWORD
Set them before startup or pass an explicit HellnetCacheOptions:
# Minimal example:
export HELLNET_CACHE_VALKEY_CONNECTION=valkey.hellnet.com.br:6379
export HELLNET_CACHE_VALKEY_PASSWORD=your-password
# Or in code:
services.AddHellnetCache(new HellnetCacheOptions {
ValkeyConnection = "valkey.hellnet.com.br:6379",
ValkeyPassword = "your-password",
});
Usage
public class OrderService(ICache cache)
{
// ── Set with per-key TTL ────────────────────────────
public async Task SetOrderAsync(Order order)
=> await cache.SetAsync(
$"order:{order.Id}",
order,
TimeSpan.FromHours(1)); // ← TTL por chave
public async Task SetSessionAsync(string id, Session s)
=> await cache.SetAsync(
$"session:{id}",
s,
TimeSpan.FromMinutes(5)); // ← TTL curto
// ── Get ─────────────────────────────────────────────
public async Task<Order?> GetOrderAsync(string id)
=> await cache.GetAsync<Order>($"order:{id}");
// ── GetOrSet (stampede-protected) ───────────────────
public async Task<Config> GetConfigAsync()
=> await cache.GetOrSetAsync(
"config:global",
async () => await _db.Configs.FirstAsync(),
TimeSpan.FromHours(24)); // ← TTL longo
// ── Remove ──────────────────────────────────────────
public async Task InvalidateOrderAsync(string id)
=> await cache.RemoveAsync($"order:{id}");
// ── Exists ──────────────────────────────────────────
public async Task<bool> HasOrderAsync(string id)
=> await cache.ExistsAsync($"order:{id}");
}
TTL per key
Cada SetAsync/GetOrSetAsync aceita TimeSpan? ttl. Quando omitido, usa o fallback do options.
// TTL explícito — cada chave com lifetime próprio
await cache.SetAsync("a", v, TimeSpan.FromMinutes(5)); // 5 min
await cache.SetAsync("b", v, TimeSpan.FromHours(24)); // 24h
await cache.SetAsync("c", v); // fallback: DefaultTtl (30min)
// L2 (Valkey) respeita o TTL exato passado
// L1 (Memory) usa absolute expiration por padrão
Architecture
ICache.GetAsync("key")
├─ L1 (Memory) ── hit? → retorna
├─ L2 (Valkey) ── hit? → popula L1, retorna
└─ L3 (External) ─ hit? → popula L2+L1, retorna
└─ miss → null
ICache.SetAsync("key", value, ttl)
├─ L1.SetAsync (absolute TTL) ── paralelo
├─ L2.SetAsync (Valkey TTL) ── paralelo
└─ L3.SetAsync (se habilitado) ── paralelo
Concurrency
| Mechanism | What it prevents |
|---|---|
| Per-key SemaphoreSlim | Cache stampede em GetOrSetAsync — só 1 request executa a factory por key |
| Semaphore auto-cleanup | TryRemove + Dispose após factory — sem memory leak |
| Warming dedup | ConcurrentDictionary flag — só 1 warming por key por vez |
| Touch-on-read | TouchOnRead=true estende TTL em todas camadas no hit |
| Parallel writes | Task.WhenAll — Set/Remove em todas camadas simultaneamente |
Options
Env-first — obrigatórias
| Env var | Required for | Description |
|---|---|---|
HELLNET_CACHE_VALKEY_CONNECTION |
AddHellnetCache() |
Valkey host:port |
HELLNET_CACHE_VALKEY_PASSWORD |
Always (when L2 enabled) | Valkey password |
DI method vs validation
| Method | Requires env | Throws if missing |
|---|---|---|
AddHellnetCache() |
VALKEY_CONNECTION + VALKEY_PASSWORD |
✅ |
AddHellnetCache(options) |
Nada (vc passa explícito) | ❌ (responsabilidade sua) |
Via env vars (HELLNET_CACHE_*)
| Env var | Default | Description |
|---|---|---|
HELLNET_CACHE_VALKEY_CONNECTION |
(obrigatório) | Valkey host:port |
HELLNET_CACHE_VALKEY_PASSWORD |
— | Valkey password |
HELLNET_CACHE_VALKEY_KEY_PREFIX |
hellnet:cache: |
Key prefix |
HELLNET_CACHE_L1_DEFAULT_TTL |
00:05:00 |
L1 fallback TTL |
HELLNET_CACHE_DEFAULT_TTL |
00:30:00 |
Global fallback TTL |
HELLNET_CACHE_MAX_TTL |
24:00:00 |
Safety cap |
HELLNET_CACHE_TOUCH_ON_READ |
false |
Auto-extend TTL on hit |
HELLNET_CACHE_TOUCH_TTL |
00:10:00 |
Extension amount |
HELLNET_CACHE_L1_SLIDING_EXPIRATION |
false |
Sliding (true) vs Absolute (false) |
HELLNET_CACHE_VALKEY_RETRY_COUNT |
2 |
Max retry attempts (Polly) |
HELLNET_CACHE_VALKEY_RETRY_BASE_DELAY_MS |
200 |
Base retry delay (exponential) |
HELLNET_CACHE_VALKEY_CB_FAILURES |
5 |
Failures before circuit opens |
HELLNET_CACHE_VALKEY_CB_DURATION_SEC |
30 |
Circuit break duration (s) |
HELLNET_CACHE_ENABLE_L1 |
true |
Enable L1 |
HELLNET_CACHE_ENABLE_L2 |
true |
Enable L2 |
HELLNET_CACHE_ENABLE_EXTERNAL |
false |
Enable L3 |
Via code
new HellnetCacheOptions
{
ValkeyConnection = "valkey.hellnet.com.br:6379",
ValkeyPassword = "hellnet2026",
ValkeyKeyPrefix = "myapp:cache:",
L1DefaultTtl = TimeSpan.FromMinutes(2),
DefaultTtl = TimeSpan.FromMinutes(15),
TouchOnRead = true,
TouchTtl = TimeSpan.FromMinutes(5),
L1SlidingExpiration = true,
};
Dependencies
- .NET 10+
StackExchange.Redis— L2 Valkey providerMicrosoft.Extensions.Caching.Memory— L1 memory providerMicrosoft.Extensions.DependencyInjection.AbstractionsMicrosoft.Extensions.Logging.Abstractions
Testing
# Unit tests (72)
dotnet test app/Hellnet.Cache.slnx
# Integration tests against real Valkey (14)
dotnet test app/tests/Hellnet.Cache.IntegrationTests/
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- Microsoft.Extensions.Caching.Memory (>= 10.0.9)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Polly.Core (>= 8.5.2)
- StackExchange.Redis (>= 2.8.31)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.