Class OptimisticConcurrencyStrategy

Namespace
Cratis.Chronicle.EventSequences.Concurrency
Assembly
Cratis.Chronicle.dll

Represents an optimistic concurrency strategy for managing concurrency scopes.

public class OptimisticConcurrencyStrategy : IConcurrencyScopeStrategy
Inheritance
OptimisticConcurrencyStrategy
Implements
Inherited Members
Extension Methods

Constructors

OptimisticConcurrencyStrategy(IEventSequence)

Initializes a new instance of the OptimisticConcurrencyStrategy class without options.

public OptimisticConcurrencyStrategy(IEventSequence eventSequence)

Parameters

eventSequence IEventSequence

The IEventSequence to use for getting the tail sequence number.

Remarks

Kept as its own constructor rather than folded into the one above with a default argument, so that code compiled against a build without ConcurrencyOptions keeps binding to a constructor that exists. Behaves as CheckFirstAppendIntoAScopeByDefault says.

OptimisticConcurrencyStrategy(IEventSequence, ConcurrencyOptions?)

Represents an optimistic concurrency strategy for managing concurrency scopes.

public OptimisticConcurrencyStrategy(IEventSequence eventSequence, ConcurrencyOptions? options)

Parameters

eventSequence IEventSequence

The IEventSequence to use for getting the tail sequence number.

options ConcurrencyOptions

The ConcurrencyOptions deciding whether the first append into a scope is checked. Null falls back to CheckFirstAppendIntoAScopeByDefault.

Methods

GetScope(ConcurrencyDimensions, EventSourceId, EventStreamType?, EventStreamId?, EventSourceType?, IEnumerable<EventType>?)

Gets the ConcurrencyScope, narrowed to the dimensions an event source or event stream declares.

public Task<ConcurrencyScope> GetScope(ConcurrencyDimensions dimensions, EventSourceId eventSourceId, EventStreamType? eventStreamType = null, EventStreamId? eventStreamId = null, EventSourceType? eventSourceType = null, IEnumerable<EventType>? eventTypes = null)

Parameters

dimensions ConcurrencyDimensions

The ConcurrencyDimensions that take part in the scope.

eventSourceId EventSourceId

The EventSourceId being appended to.

eventStreamType EventStreamType

Optional EventStreamType being appended to.

eventStreamId EventStreamId

Optional EventStreamId being appended to.

eventSourceType EventSourceType

Optional EventSourceType being appended to.

eventTypes IEnumerable<EventType>

Optional event types to scope the check to.

Returns

Task<ConcurrencyScope>

The ConcurrencyScope.

Remarks

None declares nothing and gives the same scope as the scope without dimensions. The default implementation leaves out the stream and event source type dimensions that are not declared, and always includes the event source id; a strategy that can also leave the event source id out overrides it.

GetScope(EventSourceId, EventStreamType?, EventStreamId?, EventSourceType?, IEnumerable<EventType>?)

Gets a ConcurrencyScope for the specified parameters.

public Task<ConcurrencyScope> GetScope(EventSourceId eventSourceId, EventStreamType? eventStreamType = null, EventStreamId? eventStreamId = null, EventSourceType? eventSourceType = null, IEnumerable<EventType>? eventTypes = null)

Parameters

eventSourceId EventSourceId

The EventSourceId to scope to.

eventStreamType EventStreamType

Optional EventStreamType to scope to. Defaults to All.

eventStreamId EventStreamId

Optional EventStreamId to scope to. Defaults to Default.

eventSourceType EventSourceType

Optional EventSourceType to scope to. Defaults to Default.

eventTypes IEnumerable<EventType>

Optional collection of EventType to scope to. Defaults to no specific event types.

Returns

Task<ConcurrencyScope>

The ConcurrencyScope.

Remarks

The expected sequence number is read with the same narrowing the scope declares, because that is what the kernel validates the append against. Reading a broader tail than the kernel compares to would report a conflict between appends the scope says are independent; reading a narrower one would let a real conflict through. The two have to be asked the same question.

When nothing matches that narrowing the tail read answers Unavailable, which also means "no sequence number was supplied" and is therefore skipped by the kernel. That is what the scope carries by default, so the first append into a scope goes through unchecked exactly as it always has. With CheckFirstAppendIntoAScope turned on the scope says BeforeFirst instead - the expectation a first append actually has, and one the kernel checks.