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

original ReactorDelivery

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

Reactor ReactorId

The ReactorId of the reactor the event is delivered to.

EventStore EventStoreName

The EventStoreName the event belongs to.

Namespace EventStoreNamespaceName

The EventStoreNamespaceName the event belongs to.

EventSequence EventSequenceId

The EventSequenceId the reactor observes.

Partition EventSourceId

The EventSourceId partition the event is observed in.

SequenceNumber EventSequenceNumber

The 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

uint

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

Type

EventSequence

The EventSequenceId the reactor observes.

public EventSequenceId EventSequence { get; init; }

Property Value

EventSequenceId

EventStore

The EventStoreName the event belongs to.

public EventStoreName EventStore { get; init; }

Property Value

EventStoreName

Id

Gets the stable identity of this delivery.

public DeliveryId Id { get; }

Property Value

DeliveryId

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

EventStoreNamespaceName

Partition

The EventSourceId partition the event is observed in.

public EventSourceId Partition { get; init; }

Property Value

EventSourceId

Reactor

The ReactorId of the reactor the event is delivered to.

public ReactorId Reactor { get; init; }

Property Value

ReactorId

SequenceNumber

The EventSequenceNumber of the event within the event sequence.

public EventSequenceNumber SequenceNumber { get; init; }

Property Value

EventSequenceNumber

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

Reactor ReactorId
EventStore EventStoreName
Namespace EventStoreNamespaceName
EventSequence EventSequenceId
Partition EventSourceId
SequenceNumber EventSequenceNumber

Equals(ReactorDelivery?)

public virtual bool Equals(ReactorDelivery? other)

Parameters

other ReactorDelivery

Returns

bool

Equals(object?)

public override bool Equals(object? obj)

Parameters

obj object

Returns

bool

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

reactor ReactorId

The ReactorId the event is delivered to.

eventSequence EventSequenceId

The EventSequenceId the reactor observes.

eventContext EventContext

The 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

reactor object

The reactor instance the event is delivered to.

eventContext EventContext

The EventContext of the event being delivered.

Returns

ReactorDelivery

The ReactorDelivery identifying the delivery.

Exceptions

TypeMustImplementReactor

Thrown when reactor is not a reactor.

GetHashCode()

public override int GetHashCode()

Returns

int

IdempotencyKeyFor(string)

public IdempotencyKey IdempotencyKeyFor(string effect)

Parameters

effect string

The 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 effect is null or empty.

PrintMembers(StringBuilder)

protected virtual bool PrintMembers(StringBuilder builder)

Parameters

builder StringBuilder

Returns

bool

ToString()

public override string ToString()

Returns

string

Operators

operator ==(ReactorDelivery?, ReactorDelivery?)

public static bool operator ==(ReactorDelivery? left, ReactorDelivery? right)

Parameters

left ReactorDelivery
right ReactorDelivery

Returns

bool

operator !=(ReactorDelivery?, ReactorDelivery?)

public static bool operator !=(ReactorDelivery? left, ReactorDelivery? right)

Parameters

left ReactorDelivery
right ReactorDelivery

Returns

bool