Class OptimisticConcurrencyStrategy
- 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
eventSequenceIEventSequenceThe 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
eventSequenceIEventSequenceThe IEventSequence to use for getting the tail sequence number.
optionsConcurrencyOptionsThe 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
dimensionsConcurrencyDimensionsThe ConcurrencyDimensions that take part in the scope.
eventSourceIdEventSourceIdThe EventSourceId being appended to.
eventStreamTypeEventStreamTypeOptional EventStreamType being appended to.
eventStreamIdEventStreamIdOptional EventStreamId being appended to.
eventSourceTypeEventSourceTypeOptional EventSourceType being appended to.
eventTypesIEnumerable<EventType>Optional event types to scope the check to.
Returns
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
eventSourceIdEventSourceIdThe EventSourceId to scope to.
eventStreamTypeEventStreamTypeOptional EventStreamType to scope to. Defaults to All.
eventStreamIdEventStreamIdOptional EventStreamId to scope to. Defaults to Default.
eventSourceTypeEventSourceTypeOptional EventSourceType to scope to. Defaults to Default.
eventTypesIEnumerable<EventType>Optional collection of EventType to scope to. Defaults to no specific event types.
Returns
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.