Ruvio.Extensions.Caching 0.1.0

dotnet add package Ruvio.Extensions.Caching --version 0.1.0
                    
NuGet\Install-Package Ruvio.Extensions.Caching -Version 0.1.0
                    
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="Ruvio.Extensions.Caching" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ruvio.Extensions.Caching" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Ruvio.Extensions.Caching" />
                    
Project file
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 Ruvio.Extensions.Caching --version 0.1.0
                    
#r "nuget: Ruvio.Extensions.Caching, 0.1.0"
                    
#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 Ruvio.Extensions.Caching@0.1.0
                    
#: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=Ruvio.Extensions.Caching&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Ruvio.Extensions.Caching&version=0.1.0
                    
Install as a Cake Tool

Ruvio.Extensions.Caching

Binary-safe IDistributedCache for .NET 8, using Microsoft.Extensions packages only; there is no ASP.NET Core shared-framework dependency.

using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Ruvio.Client;
using Ruvio.Extensions.Caching;

// Connect during application startup. Keep this connection alive for the app lifetime.
await using var client = await RuvioClient.ConnectAsync("localhost", 6379);
services.AddSingleton<IRuvioClient>(client);
services.AddRuvioDistributedCache(options => options.InstanceName = "orders");
// Resolve IDistributedCache through DI in application code.
await cache.SetAsync("invoice:42", new byte[] { 0, 255, 128 },
    new DistributedCacheEntryOptions
    {
        SlidingExpiration = TimeSpan.FromMinutes(5),
        AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
    }, cancellationToken);

The application owns the client. This provider never connects or disposes it. An injected substitute must implement IRuvioClient.ExecuteBinaryAsync; the default interface implementation explicitly rejects unsupported binary commands. Registration uses TryAdd, preserving an existing IDistributedCache. Options are validated at registration and construction and then snapshotted; no hot reload is performed.

Contract and expiration

  • Empty keys and zero-byte values are valid; null keys, values, and entry options are rejected. A missing key returns null; an empty value returns an empty array.
  • All byte values round-trip directly as RESP bulk strings, including invalid UTF-8. Keys and namespaces are strict UTF-8. Do not modify input bytes until Set completes.
  • Set is one SET, with PX or PXAT when the entry expires. Get and Refresh are one GET. A sliding entry then sends one short EVAL that applies PEXPIREAT only when the stored bytes are still the ones just read, so a replacement does not receive the previous lifetime. Remove is one DEL. Get renews sliding expiration before returning; Refresh does not return the payload.
  • Sliding renewal never extends the absolute deadline. When both absolute options are specified, the earlier deadline wins. Relative absolute expiration is converted to a UTC deadline in SetAsync before dispatch, using the client's clock. Explicit and relative absolute expiration both require synchronized client/server UTC clocks. Queueing/network time consumes the remaining lifetime; deadlines already past on the server produce no live entry. Sliding-only expiration uses the server's relative TTL.
  • Millisecond resolution: positive durations below 1 ms are rejected; fractional milliseconds are rounded down. Absolute deadlines are rounded down to Unix ms and must be future at dispatch. Expired entries are never revived by a read or refresh.
  • Set writes the final envelope and its expiry in one SET. Sliding renewal uses the client clock and never passes the stored absolute deadline.
  • Server/protocol/corrupt-envelope errors propagate; they never become cache misses. Cancellation propagates, but cancellation/disconnection after sending cannot prove whether a mutation ran. No transport-failure mutation replay is performed. Atomic isolation is not a rollback guarantee: server resource/script-limit failures after a script has begun mutating can affect the entry or its TTL. Older Ruvio servers without expiration-aware script rollback do not restore native key TTLs. Treat a failed mutation/renewal as an uncertain outcome and reconcile or remove the affected entry; do not rely on its previous expiration or blindly retry the mutation. Explicit MOVED redirects may be followed because the server rejected that command. Sync methods block on their async equivalent on the thread pool (avoiding caller synchronization-context deadlocks). This adds scheduling overhead; prefer async code.

Storage, limits, and operations

The physical key is <InstanceName>:ruvio:cache:v1:<key>. Reserve this namespace for this provider; do not edit the stored values or TTLs with other clients. Cluster hash tags in keys/namespaces retain their normal meaning. Scripts declare exactly one key and work with the client's cluster routing.

One native string entry contains RDC1\n<absolute-ms-or-0>\n<sliding-ms-or-0>\n<payload>. The envelope costs 9–37 bytes (ASCII decimal fields), not base64 expansion. Native key/object/index overhead is additional and implementation-dependent. Persistent entries have no TTL; no extra metadata keys, hash fields, polling tasks, timers, or server changes are introduced. Sliding-only entries use only native expiry plus the in-value sliding duration. The provider adds no telemetry or key/value logging.

Defaults: 1 MiB payload and 1024 UTF-8 bytes for the full namespaced key. MaxValueBytes (zero allows only empty values) and MaxKeyBytes are configurable. The client RESP bulk ceiling is 64 MiB; the provider reserves 64 bytes for the envelope. Server protocol/value/request limits and script limits must also accommodate the envelope and the SET command; increasing provider limits does not raise server limits. Only a sliding renewal sends EVAL, and that script is one fixed text cached on the shard.

Tests

dotnet test integrations/dotnet/Ruvio.Extensions.Caching.Tests
RUVIO_TEST_ADDR=127.0.0.1:6379 dotnet test integrations/dotnet/Ruvio.Extensions.Caching.Tests

Live tests are explicitly skipped unless RUVIO_TEST_ADDR is set. They use unique namespaces and clean up their own keys (never FLUSHDB). Use an isolated disposable server for the live suite; it exercises expiration and concurrent writers.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 93 10/2/2026