OrionLock.Redis 3.0.0

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

OrionLock.Redis

Redis backend for OrionLock. SET NX PX acquire with owner-checked Lua compare-and-extend / compare-and-delete.

services.AddOrionLock().UseRedis("localhost:6379");

Which connection the locks use

UseRedis(connectionString) connects with that connection string, and keeps the resulting multiplexer under a private DI key. Your application's own IConnectionMultiplexer — the one the cache uses — is neither read nor replaced. (It used to be registered with TryAddSingleton, so an app that had already registered one silently got its connection string discarded and locked against the cache's Redis instead.)

UseRedis() with no connection string is the opt-in to sharing: it resolves the application's registered IConnectionMultiplexer.

This package also ships the distributed reader-writer (shared/exclusive) lock. UseRedisSharedExclusive() registers ISharedExclusiveLock over Redis, additive to UseRedis():

services.AddOrionLock()
    .UseRedis("localhost:6379")
    .UseRedisSharedExclusive();

It keeps a Lua-scripted writer marker, a per-reader sorted set scored by lease expiry (so one reader's expiry never frees another's), and a lease-bounded pending-writer marker that holds off new readers so a waiting writer is not starved. All lease math uses the Redis server clock, and renew/release are owner-token checked.

Fencing tokens

Off by default. Turn it on and every acquire also returns a handle.FencingToken: an INCR on a per-key counter issued in the same Lua call as the SET NX PX, so the token and the lock are taken atomically and the number strictly increases per key across processes.

services.AddOrionLock().UseRedis("localhost:6379", o => o.FencingTokens = true);

It is opt-in because the counter key can never expire or be deleted — one that restarted would hand a later holder a token an earlier one already spent — so enabling it leaves one small permanent orionlock-fence:{key} key per lock key you take.

Counters live under that reserved orionlock-fence: prefix so no lock key can also be somebody's counter; with fencing on, a lock key that would resolve into that namespace is rejected with an ArgumentException. With the default orionlock: prefix the rejection can never fire. See the OrionLock docs on fencing tokens for what to do with the number.

Lease durations

Both providers round a lease up to whole milliseconds, so the shortest lock you can take is 1 ms. A lease of zero or less is rejected with ArgumentOutOfRangeException rather than accepted: PX 0 / PEXPIRE 0 does not mean "expire immediately" in Redis, it DELETES the key, which would drop the lock at its first renewal.

Waiting subscribes, it does not poll

A contended waiter subscribes to a per-key release channel and parks instead of issuing a SET NX every RetryInterval. A release publishes to that channel fire-and-forget, so waking every waiter on the key costs the releasing caller no extra round trip, and a notification that cannot be delivered can never fail a release.

A dedicated channel, not keyspace notifications. Keyspace notifications would need notify-keyspace-events enabled on the server: it is off by default, a client library cannot turn it on, and on a managed Redis it may not be configurable at all - a lock that silently never notified would be worse than one that polls. The channel OrionLock publishes to itself works on any Redis, through a replica or a proxy. There is no server-side configuration to do. The channel is {KeyPrefix}{key}{ReleaseChannelSuffix}, default suffix :released.

What a channel cannot cover is a lock freed by TTL: a crashed holder publishes nothing. A waiter therefore also bounds its wait by the holder's remaining TTL, read once per wait rather than once per retry interval, so an expiry is still noticed promptly.

Set RedisLockOptions.UseReleaseNotifications = false on a deployment where pub/sub is unavailable or undesirable; waiters then fall back to exactly the poll loop earlier releases used.

FIFO waiter fairness

RedisFifoWaiterCoordinator orders waiters by arrival millisecond, with a per-process sequence breaking ties inside one millisecond. Two waiters in the same millisecond in different processes still fall back to member ordering — cross-process sub-millisecond ordering is not a guarantee this coordinator makes.

Requires the OrionLock package. See https://github.com/tunahanaliozturk/OrionLock.

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 (1)

Showing the top 1 NuGet packages that depend on OrionLock.Redis:

Package Downloads
OrionGuard.Locks.Redis

Redis-backed IDistributedLock for OrionGuard.EntityFrameworkCore's outbox dispatcher. Bridges OrionGuard's IDistributedLock contract to the OrionLock.Redis backend so multi-instance outbox workers can share a Redis-coordinated lease instead of the default SkipLocked DB lock.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 93 9/20/2026
2.0.0 427 7/29/2026
1.0.1 122 7/27/2026
1.0.0 135 6/30/2026
0.6.0 126 6/27/2026
0.5.0 148 6/26/2026
0.4.1 136 6/20/2026
0.4.0 130 6/19/2026
0.3.32 156 6/17/2026
0.3.31 153 6/16/2026
0.3.30 164 6/16/2026
0.3.28 149 6/15/2026
0.3.27 162 6/15/2026
0.3.26 181 6/13/2026
0.3.25 186 6/13/2026
0.3.24 192 6/12/2026
0.3.23 199 6/12/2026
0.3.22 193 6/11/2026
0.3.21 194 6/11/2026
0.3.20 202 6/11/2026
Loading failed