DistributedLockManager is a robust .NET library for distributed locking using Redis and the RedLock algorithm. It is designed for scalable applications that require distributed synchronization and safe resource access across multiple processes or services.
- Redis-based distributed locking (RedLock algorithm)
- Supports both void and result-returning operations
- Configurable lock expiry, wait, and retry times
- Cancellation support via
CancellationToken - Easy integration with dependency injection
- Thread-safe and automatic lock release
Install via NuGet (coming soon):
dotnet add package Tricksfor.DistributedLockManagerOr build from source:
dotnet build DistributedLockManager.sln -c Release- .NET 8.0 or later
- Redis server (local, docker or remote)
Add the required services to your dependency injection container:
services.AddDistributedLockManager();You do not need to manually register IConnectionMultiplexer if you have already added Redis to your Aspire project as described in the Microsoft Aspire documentation.
Register the Redis connection multiplexer:
services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect("localhost:6379"));You can use the distributed lock service for both void and result-returning operations. Here is an example similar to the integration tests:
// For operations that return a value
var distributedLockService = serviceProvider.GetRequiredService<IDistributedLockService<TResult>>();
var result = await distributedLockService.RunWithLockAsync(
async () => await ProcessDataAsync(),
CancellationToken.None
);await distributedLockService.RunWithLockAsync(
async () => await ProcessDataAsync(),
"process-data-lock",
CancellationToken.None
);await distributedLockService.RunWithLockAsync(
async () => await LongRunningOperation(),
"long-operation-lock",
CancellationToken.None,
expiryInSecond: 60, // Lock expires after 60 seconds
waitInSecond: 15, // Wait up to 15 seconds to acquire lock
retryInSecond: 2 // Retry every 2 seconds
);expiryInSecond: Duration the lock is held (default: 30 seconds)waitInSecond: Max time to wait for lock (default: 10 seconds)retryInSecond: Time between retries (default: 1 second)
InvalidOperationException is thrown if:
- Lock acquisition fails after the wait time
- The resource is already locked
Example:
try
{
await _lockService.RunWithLockAsync(...);
}
catch (InvalidOperationException ex)
{
// Handle lock acquisition failure
}
catch (Exception ex)
{
// Handle other errors
}This project is licensed under the MIT License. See the LICENSE file for details.