Skip to main content
Table of Contents

Class BucketLockPool

Namespace
Stratara.Abstractions.Partitioning
Assembly
Stratara.Abstractions.dll

Pre-allocated pool of per-bucket locks that serialises work keyed on an aggregate identity.

public sealed class BucketLockPool : IDisposable
Inheritance
BucketLockPool
Implements
Inherited Members
Extension Methods

Remarks

One SemaphoreSlim is allocated per bucket at construction, so the steady-state acquire path is a single indexed read with no allocation and no dictionary lookup. The bucket of an identity is its hash modulo BucketCount; two identities that share a bucket serialise against each other, which costs throughput and never correctness. The command worker uses the pool to run commands naming one aggregate one at a time, and the projection and saga workers use it to apply bundles about one aggregate one at a time — each within its own process.

Constructors

BucketLockPool()

Initializes a pool with one lock per bucket.

public BucketLockPool()

Fields

BucketCount

The number of buckets, and therefore of locks, the pool holds.

public const int BucketCount = 4096

Field Value

int

Methods

AcquireAsync(int, CancellationToken)

Acquires the lock for bucketId, waiting until it is free. Dispose the returned releaser to let the next waiter through; disposing it twice releases once.

public ValueTask<IDisposable> AcquireAsync(int bucketId, CancellationToken cancellationToken)

Parameters

bucketId int

The bucket to lock, in [0, BucketCount).

cancellationToken CancellationToken

Cancels the wait.

Returns

ValueTask<IDisposable>

A releaser that frees the bucket when disposed.

Exceptions

ArgumentOutOfRangeException

bucketId is negative or not below BucketCount.

OperationCanceledException

The wait was cancelled.

ObjectDisposedException

The pool has been disposed.

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()