Lyo.Lock
2.0.0
See the version list below for details.
dotnet add package Lyo.Lock --version 2.0.0
NuGet\Install-Package Lyo.Lock -Version 2.0.0
<PackageReference Include="Lyo.Lock" Version="2.0.0" />
<PackageVersion Include="Lyo.Lock" Version="2.0.0" />
<PackageReference Include="Lyo.Lock" />
paket add Lyo.Lock --version 2.0.0
#r "nuget: Lyo.Lock, 2.0.0"
#:package Lyo.Lock@2.0.0
#addin nuget:?package=Lyo.Lock&version=2.0.0
#tool nuget:?package=Lyo.Lock&version=2.0.0
Lyo.Lock
Exclusive locks by key and keyed semaphores (bounded concurrency per key), plus in-memory implementations for a single process.
Features
- ILockService. Acquire/release by string key, or
ExecuteWithLockAsynchelpers that throwTimeoutExceptionif the lock is not obtained. - LocalLockService.
SemaphoreSlimgives one holder per normalized key. - IKeyedSemaphoreService. Up to
maxConcurrencysimultaneous permit holders per key. - LocalKeyedSemaphoreService. Per-key
SemaphoreSlimwith ref-counted cleanup when idle. - Key normalization. By default keys are compared case-insensitively (
ToLowerInvariant). Set skip when keys are already normalized. - DI.
AddLocalLock,AddLocalLockFromConfiguration,AddLocalKeyedSemaphore,AddLocalKeyedSemaphoreFromConfiguration. - Metrics. Optional timers/counters via
Lyo.MetricswhenEnableMetricsis true andIMetricsis registered.
Examples
First steps
using Lyo.Lock;
using Microsoft.Extensions.DependencyInjection;
services.AddLocalLock();
services.AddLocalKeyedSemaphore();
// Optional: bind appsettings → LockOptions / KeyedSemaphoreOptions
services.AddLocalLockFromConfiguration(configuration);
services.AddLocalKeyedSemaphoreFromConfiguration(configuration);
First steps (2)
// Exclusive lock: null if timeout
var handle = await lockService.AcquireAsync("order:123", timeout: TimeSpan.FromSeconds(5));
if (handle is not null)
{
await using (handle)
await ProcessOrderAsync();
}
// Throws TimeoutException if not acquired
await lockService.ExecuteWithLockAsync("order:123", async ct => await ProcessOrderAsync(ct));
// Up to 3 concurrent operations for the same key (same process only)
await semaphoreService.ExecuteAsync("export:tenant-1", 3, async ct => await RunExportAsync(ct));
KeyedSemaphoreOptions (section KeyedSemaphoreOptions)
{
"LockOptions": {
"DefaultAcquireTimeout": "00:00:30",
"DefaultLockDuration": "00:01:00",
"KeyPrefix": "lyo:lock:",
"EnableMetrics": false,
"SkipKeyNormalization": false
},
"KeyedSemaphoreOptions": {
"DefaultAcquireTimeout": "00:00:30",
"SkipKeyNormalization": false,
"EnableMetrics": false
}
}
Benchmarks
- Portfolio suite:
lock
Which one to pick
| Primitive | Type | Scope | Typical use |
|---|---|---|---|
ILockService / LocalLockService |
Per-key mutex | Single process | Guard mutations to one aggregate, avoid duplicate work, serialize handlers per entity ID |
IKeyedSemaphoreService / LocalKeyedSemaphoreService |
Per-key counting semaphore | Single process | Cap concurrent exports/API calls/backfills per tenant or resource key without global rate limits |
More than one server or process needs a distributed ILockService (see Lyo.Lock.Redis). Keyed semaphores in this package stay process-local.
First steps
Inject IKeyedSemaphoreService and/or ILockService:
Keyed-semaphore rules
- Keep
maxConcurrencystable for a given key while any permit is held or waiters exist. If you pass a differentmaxConcurrencyfor an active key,LocalKeyedSemaphoreServicethrowsInvalidOperationExceptioninstead of undefined behavior. - Cancellation tokens on
ExecuteAsync/AcquireAsyncare honored while waiting.
LockOptions (LockOptions section)
| Property | Default | Description |
|---|---|---|
DefaultAcquireTimeout |
30s | Ceiling wait for ExecuteWithLockAsync / AcquireAsync. |
DefaultLockDuration |
60s | Used by distributed locks (Redis TTL). Ignored by LocalLockService. |
KeyPrefix |
lyo:lock: |
Prefix for Redis keys; harmless for local-only usage. |
SkipKeyNormalization |
false |
When true, keys are not lowercased (caller must ensure consistent casing). |
EnableMetrics |
false |
Record lock timings/counters when IMetrics is available. |
KeyedSemaphoreOptions (section KeyedSemaphoreOptions)
| Property | Default | Description |
|---|---|---|
DefaultAcquireTimeout |
30s | Ceiling wait for a permit. |
SkipKeyNormalization |
false |
Same semantics as lock options. |
EnableMetrics |
false |
Record semaphore timings/counters when IMetrics is available. |
Example appsettings.json:
Metrics (Constants)
With metrics on and IMetrics in the container, names follow Lyo.Lock.Constants:
Locks (Constants.Metrics)
| Name | Role |
|---|---|
lock.acquire.duration |
Time spent waiting to acquire |
lock.acquire.success / lock.acquire.failure |
Counter |
lock.release.duration |
Time to release |
lock.execute.duration |
Wall time for ExecuteWithLockAsync |
Semaphores (Constants.SemaphoreMetrics)
| Name | Role |
|---|---|
semaphore.acquire.duration |
Wait time for a permit |
semaphore.acquire.success / semaphore.acquire.failure |
Counter |
semaphore.release.duration |
Release timing |
semaphore.execute.duration |
Wall time for ExecuteAsync |
The key tag is the logical key string the caller passed (XML docs on Constants describe it).
Methods on ILockService
- AcquireAsync. Returns
ILockHandle?(nullon timeout). - ExecuteWithLockAsync / ExecuteWithLockAsync<T>. Acquire, run the delegate, release. Throw
TimeoutExceptionif not acquired.
Methods on ILockHandle / IPermitHandle
- ReleaseAsync. Idempotent after the first release.
- Dispose / DisposeAsync. Release. Sync dispose may block briefly on the internal
ReleaseAsync.
Methods on IKeyedSemaphoreService
- AcquireAsync. Returns
IPermitHandle?on timeout. - ExecuteAsync / ExecuteAsync<T>. Throw
TimeoutExceptionif no permit.
Dependencies
Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).
Lyo.Configuration(direct, lyo)Lyo.Exceptions(direct, lyo)Lyo.Metrics(direct, lyo)Microsoft.Extensions.DependencyInjection.Abstractions10.0.5(direct, microsoft)Microsoft.Extensions.Logging.Abstractions10.0.5(direct, microsoft)Microsoft.Extensions.Configuration.Binder10.0.5(transitive, microsoft)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Lyo.Configuration (>= 2.0.0)
- Lyo.Exceptions (>= 2.0.0)
- Lyo.Metrics (>= 2.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
-
net10.0
- Lyo.Configuration (>= 2.0.0)
- Lyo.Exceptions (>= 2.0.0)
- Lyo.Metrics (>= 2.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Lyo.Lock:
| Package | Downloads |
|---|---|
|
Lyo.FileMetadataStore.Postgres
PostgreSQL implementation of the Lyo FileMetadataStore service using Entity Framework Core. |
|
|
Lyo.FileMetadataStore.Sqlite
SQLite implementation of the Lyo FileMetadataStore service using Entity Framework Core. |
|
|
Lyo.Lock.Redis
Redis-based distributed lock implementation for Lyo.Lock. Uses StackExchange.Redis for multi-instance coordination. |
GitHub repositories
This package is not used by any popular GitHub repositories.