Event Sequences
Event sequences are a shared Chronicle concept. Use the shared docs for the event log, custom sequences, filtering, and appending behavior.
The sections below cover Chronicle.EventSequences.EventLog APIs that are new to the
Elixir client and not yet covered by the shared docs above.
Redacting events
Section titled “Redacting events”Redaction permanently erases an event’s content for compliance/GDPR erasure. Unlike
compliance encryption (reversible via key rotation), this overwrites the event’s content
in the log for good. Mirrors the C# and TypeScript clients’ IEventSequence.Redact().
Redact a single event by its sequence number, with a reason:
:ok = Chronicle.EventSequences.EventLog.redact(sequence_number, "Customer requested erasure")Redact every event for an event source in one call — for example, to erase all data for a specific user:
:ok = Chronicle.EventSequences.EventLog.redact_for_event_source( event_source_id, "Account closed under GDPR" )Narrow a bulk redaction to specific event types by passing a list of event type modules as the third argument:
:ok = Chronicle.EventSequences.EventLog.redact_for_event_source( event_source_id, "Email address was captured in error", [MyApp.Events.EmailChanged] )Both functions accept the same options as append/3 (:client, :namespace,
:event_sequence_id).
Reading forward from a sequence number
Section titled “Reading forward from a sequence number”get_from_sequence_number/2 returns events from (and including) a given sequence number
onward, optionally filtered by event source id and event types. Mirrors the C# and
TypeScript clients’ GetFromSequenceNumber().
{:ok, events} = Chronicle.EventSequences.EventLog.get_from_sequence_number(sequence_number, event_source_id: event_source_id, event_types: [MyApp.Events.OrderPlaced] )Sequence numbers
Section titled “Sequence numbers”get_tail_sequence_number/2 returns the sequence number of the last appended event.
get_next_sequence_number/2 mirrors it but returns the number that will be assigned to the
next appended event — it distinguishes “the log is empty” (returns 0) from “the tail
is at sequence 0” (returns 1), which get_tail_sequence_number/2 alone cannot do.
Mirrors the C# and TypeScript clients’ GetNextSequenceNumber().
{:ok, tail} = Chronicle.EventSequences.EventLog.get_tail_sequence_number(event_source_id){:ok, next} = Chronicle.EventSequences.EventLog.get_next_sequence_number(event_source_id)get_tail_sequence_number_for_observer/2 scopes the tail lookup to only the event types a
reactor or reducer module subscribes to (its @handles declarations), instead of every
event type. Mirrors the C# client’s GetTailSequenceNumberForObserver().
{:ok, tail} = Chronicle.EventSequences.EventLog.get_tail_sequence_number_for_observer( MyApp.Reactors.OrderNotifier )Filtering by stream
Section titled “Filtering by stream”get_for_event_source/2 and get_tail_sequence_number/2 also accept :event_source_type,
:event_stream_type, and :event_stream_id options, narrowing either call to a specific
non-default stream instead of silently ignoring these dimensions:
{:ok, events} = Chronicle.EventSequences.EventLog.get_for_event_source(event_source_id, event_stream_type: "audit-trail", event_stream_id: "2024" )Completing a stream
Section titled “Completing a stream”complete_stream/3 closes a named, non-default stream so that no further events can be
appended to it. The default stream can never be completed.
case Chronicle.EventSequences.EventLog.complete_stream("audit-trail", "2024") do {:ok, tail_sequence_number} -> :ok {:error, :default_stream_cannot_be_completed} -> :error {:error, :already_completed} -> :okendAppending and waiting for observer completion
Section titled “Appending and waiting for observer completion”append_and_wait_for_completion/3 appends a single event and then waits (default: 5
seconds) for every observer affected by the append — reactors, reducers, projections — to
either reach the appended sequence number or fail, instead of returning as soon as the
event is durably stored. Mirrors the C# client’s AppendResult.WaitForCompletion().
case Chronicle.EventSequences.EventLog.append_and_wait_for_completion( event_source_id, %MyApp.Events.OrderPlaced{customer_id: customer_id, total: total} ) do {:ok, %{success: true, failed_partitions: []}} -> :ok
{:ok, %{success: false, failed_partitions: failed_partitions}} -> # One or more observers failed or timed out — inspect failed_partitions # (a list of `Chronicle.FailedPartitions.FailedPartition`). :error
{:error, reason} -> :errorendPass :timeout (milliseconds) to override the default wait.