Skip to main content

Brook Append Outcomes

IBrookWriterGrain separates durable event append from cursor-update publication. A publication failure can occur after the events have committed.

This reference covers Mississippi.Brooks.Abstractions.Writer, the low-level writer contract used by the aggregate runtime. Application commands continue to use the Write Model.

AppendEventsAsync​

AppendEventsAsync(events, expectedCursorPosition, cancellationToken) appends events and then publishes the resulting cursor position. The caller's token is passed to storage; once storage reports commitment, publication proceeds independently of caller cancellation so committed progress is not hidden by an aborted request.

Observed outcomeMeaningCaller responsibility
Returns a BrookPositionStorage append and the publication call completed.Continue from the returned position.
Throws BrookCursorPublicationException with a supplied PositionThe writer committed the events at that position, but publication did not complete successfully.Retry publication for that position; do not append the events again.
Times out or throws another exceptionThe exception alone does not establish whether the append committed.Confirm the outcome through authoritative storage recovery before deciding what work remains.

The optional expected cursor is an optimistic concurrency precondition. Omitting it does not make retries idempotent.

BrookCursorPublicationException​

Position identifies the committed cursor when the writer supplies it. The position-bearing constructor rejects an unset or negative position; zero is the first valid committed event position. InnerException describes the publication failure. General-purpose constructors which do not receive a position leave Position unset (-1); that value is not evidence of a committed append and cannot be published.

A lost response can hide this exception from the caller. Do not classify every timeout as either a failed append or a known publication failure.

PublishCursorAsync​

PublishCursorAsync(position, cancellationToken) publishes a cursor update without appending events. The caller supplies a position confirmed by a successful append, a writer-issued publication exception, or authoritative storage recovery for the same brook.

The method rejects negative positions and checks cancellation before publication. It does not validate the supplied position against storage. Never invent a position, substitute an expected future position, or treat an unconfirmed cached position as proof of commitment.

Repeating publication can repeat the cursor notification. A successful publication call does not establish that every projection or client has caught up.

Limits​

These contracts do not make arbitrary external side effects execute exactly once. They do not dispatch aggregate effects, decide saga recovery policy, or prove that a timed-out request has stopped running.

An empty storage read does not by itself prevent a delayed append from committing later. Preserve recovery protection while that outcome remains uncertain.