OrionBeacon.Stores.Redis 0.5.0

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

OrionBeacon.Stores.Redis

A Redis-backed ILeaseStore for OrionBeacon leader election. Run the same service on several instances against a shared Redis and OrionBeacon keeps exactly one elected across the cluster, not one per process as the in-memory store does.

Why a server-side script

Leader election is only safe if acquire-or-renew is atomic: two candidates checking "is the lease free?" and then both taking it is the split-brain this library exists to prevent. This store expresses the whole decision as one Lua script, so it runs to completion on the Redis server without interleaving another candidate's commands. There is no read-then-write window.

The script does exactly what the contract requires:

  • No current leader (the lease key is absent or has expired): the caller becomes leader and the fencing token advances.
  • The caller is already the leader: the lease is renewed (its TTL is extended) and the fencing token does not change.
  • A different candidate holds a live lease: the caller is denied and told who holds it.

Fencing tokens that strictly increase

The fencing token is a Redis counter at {prefix}{resource}:fence, advanced with INCR inside the acquire path of the same script. That counter is never deleted, so even after a dead leader's lease expires and the lease key vanishes, the next candidate to take over receives a token strictly greater than every term before it. A renew reads the stored token back unchanged, so the token is stable for the life of a single leadership term and only moves when leadership does. Pass it to downstream stores to fence out a leader whose lease lapsed during a stop-the-world pause.

Lease expiry and takeover

The lease is a Redis hash carrying a TTL. A healthy leader renews within the lease window and the TTL is pushed forward each time. If the leader dies and stops renewing, Redis expires the key, the lease lapses, and the next candidate's acquire succeeds with a higher token. Release is fencing-checked: only the candidate that holds the lease can release it, so a stale caller cannot hand the resource to someone else.

Install

dotnet add package OrionBeacon.Stores.Redis

Usage

Register the Redis store before AddOrionBeacon(). AddOrionBeacon() only adds the in-process store if no ILeaseStore is already registered, so registering Redis first makes election span the cluster.

builder.Services.AddOrionBeaconRedisStore("localhost:6379");
builder.Services.AddOrionBeacon(o =>
{
    o.ResourceName = "nightly-report";
    o.LeaseDuration = TimeSpan.FromSeconds(15);
    o.RenewInterval = TimeSpan.FromSeconds(5);
});

If the application already manages its own IConnectionMultiplexer, use the overload that reuses it:

builder.Services.AddSingleton<IConnectionMultiplexer>(
    ConnectionMultiplexer.Connect("localhost:6379"));
builder.Services.AddOrionBeaconRedisStore(o => o.KeyPrefix = "myapp:lease:");
builder.Services.AddOrionBeacon(o => o.ResourceName = "jobs");

Every candidate competing for the same leadership must use the same KeyPrefix and Database so they contend over the same keys.

License

MIT, the same as OrionBeacon.

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 is compatible.  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 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.

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.5.0 125 7/28/2026
0.4.0 114 7/20/2026