Class ReactorDelivery
- Namespace
- Cratis.Chronicle.Reactors
- Assembly
- Cratis.Chronicle.dll
Represents the identity of the delivery of one event to one reactor partition.
public record ReactorDelivery : IEquatable<ReactorDelivery>
- Inheritance
-
ReactorDelivery
- Implements
- Inherited Members
- Extension Methods
Remarks
Declare a parameter of this type on a handler method and Chronicle passes it in, the same way it passes the EventContext. Every component is something Chronicle already knows about the delivery, so the identity survives everything that re-delivers an event: recovering a failed partition re-reads the same partition from the sequence number it failed on, and a replay re-reads the same sequence numbers for the same observer. Both therefore produce the same Id as the delivery they repeat.
What it does not do. It is an identity, not a guarantee. Chronicle does not know whether your side effect ran, so it cannot suppress a repeat on your behalf and this is not exactly-once delivery. Recording the identity and checking it before the effect narrows at-least-once to at-most-once only as far as your own record is atomic with the effect - a process that dies between the effect and the record still repeats the effect on the next delivery.
Compare with OnceOnlyAttribute and ReplayAttribute, which act on replay alone and need no storage. This is the seam for the case they do not cover: the ordinary re-delivery that follows a failed partition being recovered.
Constructors
ReactorDelivery(ReactorDelivery)
protected ReactorDelivery(ReactorDelivery original)
Parameters
originalReactorDelivery
ReactorDelivery(ReactorId, EventStoreName, EventStoreNamespaceName, EventSequenceId, EventSourceId, EventSequenceNumber)
Represents the identity of the delivery of one event to one reactor partition.
public ReactorDelivery(ReactorId Reactor, EventStoreName EventStore, EventStoreNamespaceName Namespace, EventSequenceId EventSequence, EventSourceId Partition, EventSequenceNumber SequenceNumber)
Parameters
ReactorReactorIdThe ReactorId of the reactor the event is delivered to.
EventStoreEventStoreNameThe EventStoreName the event belongs to.
NamespaceEventStoreNamespaceNameThe EventStoreNamespaceName the event belongs to.
EventSequenceEventSequenceIdThe EventSequenceId the reactor observes.
PartitionEventSourceIdThe EventSourceId partition the event is observed in.
SequenceNumberEventSequenceNumberThe EventSequenceNumber of the event within the event sequence.
Remarks
Declare a parameter of this type on a handler method and Chronicle passes it in, the same way it passes the EventContext. Every component is something Chronicle already knows about the delivery, so the identity survives everything that re-delivers an event: recovering a failed partition re-reads the same partition from the sequence number it failed on, and a replay re-reads the same sequence numbers for the same observer. Both therefore produce the same Id as the delivery they repeat.
What it does not do. It is an identity, not a guarantee. Chronicle does not know whether your side effect ran, so it cannot suppress a repeat on your behalf and this is not exactly-once delivery. Recording the identity and checking it before the effect narrows at-least-once to at-most-once only as far as your own record is atomic with the effect - a process that dies between the effect and the record still repeats the effect on the next delivery.
Compare with OnceOnlyAttribute and ReplayAttribute, which act on replay alone and need no storage. This is the seam for the case they do not cover: the ordinary re-delivery that follows a failed partition being recovered.
Properties
EffectEpoch
Gets the effect epoch of the reactor, taken from EffectEpoch.
public uint EffectEpoch { get; init; }
Property Value
Remarks
The epoch is not part of Id. It only separates the idempotency keys derived for the reactor's effects.
EqualityContract
protected virtual Type EqualityContract { get; }
Property Value
EventSequence
The EventSequenceId the reactor observes.
public EventSequenceId EventSequence { get; init; }
Property Value
EventStore
The EventStoreName the event belongs to.
public EventStoreName EventStore { get; init; }
Property Value
Id
Gets the stable identity of this delivery.
public DeliveryId Id { get; }
Property Value
Remarks
Use this as the key of whatever records that the side effect completed. It is derived from the record's components, so two ReactorDelivery instances that are equal always carry the same value.
Namespace
The EventStoreNamespaceName the event belongs to.
public EventStoreNamespaceName Namespace { get; init; }
Property Value
Partition
The EventSourceId partition the event is observed in.
public EventSourceId Partition { get; init; }
Property Value
Reactor
The ReactorId of the reactor the event is delivered to.
public ReactorId Reactor { get; init; }
Property Value
SequenceNumber
The EventSequenceNumber of the event within the event sequence.
public EventSequenceNumber SequenceNumber { get; init; }
Property Value
Methods
Deconstruct(out ReactorId, out EventStoreName, out EventStoreNamespaceName, out EventSequenceId, out EventSourceId, out EventSequenceNumber)
public void Deconstruct(out ReactorId Reactor, out EventStoreName EventStore, out EventStoreNamespaceName Namespace, out EventSequenceId EventSequence, out EventSourceId Partition, out EventSequenceNumber SequenceNumber)
Parameters
ReactorReactorIdEventStoreEventStoreNameNamespaceEventStoreNamespaceNameEventSequenceEventSequenceIdPartitionEventSourceIdSequenceNumberEventSequenceNumber
Equals(ReactorDelivery?)
public virtual bool Equals(ReactorDelivery? other)
Parameters
otherReactorDelivery
Returns
Equals(object?)
public override bool Equals(object? obj)
Parameters
objobject
Returns
For(ReactorId, EventSequenceId, EventContext)
Creates the ReactorDelivery for an event being delivered to a known reactor and event sequence.
public static ReactorDelivery For(ReactorId reactor, EventSequenceId eventSequence, EventContext eventContext)
Parameters
reactorReactorIdThe ReactorId the event is delivered to.
eventSequenceEventSequenceIdThe EventSequenceId the reactor observes.
eventContextEventContextThe EventContext of the event being delivered.
Returns
- ReactorDelivery
The ReactorDelivery identifying the delivery.
For(object, EventContext)
Creates the ReactorDelivery for an event being delivered to a reactor instance.
public static ReactorDelivery For(object reactor, EventContext eventContext)
Parameters
reactorobjectThe reactor instance the event is delivered to.
eventContextEventContextThe EventContext of the event being delivered.
Returns
- ReactorDelivery
The ReactorDelivery identifying the delivery.
Exceptions
- TypeMustImplementReactor
Thrown when
reactoris not a reactor.
GetHashCode()
public override int GetHashCode()
Returns
IdempotencyKeyFor(string)
Derives the IdempotencyKey for a named effect of this delivery, for use with AppendOnce(EventSourceId, object, IdempotencyKey, EventStreamType?, EventStreamId?, EventSourceType?, CorrelationId?, IEnumerable<string>?, ConcurrencyScope?, DateTimeOffset?, Subject?) or on an EventForEventSourceId the handler builds itself.
public IdempotencyKey IdempotencyKeyFor(string effect)
Parameters
effectstringThe name of the effect. Must not be empty.
Returns
- IdempotencyKey
The same key for every delivery of the same event to the same reactor partition and effect epoch.
Exceptions
- ArgumentException
Thrown when
effectis null or empty.
PrintMembers(StringBuilder)
protected virtual bool PrintMembers(StringBuilder builder)
Parameters
builderStringBuilder
Returns
ToString()
public override string ToString()
Returns
Operators
operator ==(ReactorDelivery?, ReactorDelivery?)
public static bool operator ==(ReactorDelivery? left, ReactorDelivery? right)
Parameters
leftReactorDeliveryrightReactorDelivery
Returns
operator !=(ReactorDelivery?, ReactorDelivery?)
public static bool operator !=(ReactorDelivery? left, ReactorDelivery? right)
Parameters
leftReactorDeliveryrightReactorDelivery