Skip to content

fix(store-inmemory): deliver events appended before a new subscription runs - #420

Merged
GraemeF merged 1 commit into
mainfrom
fix/inmemory-subscribe-gap
Sep 30, 2026
Merged

GraemeF merged 1 commit into
mainfrom
fix/inmemory-subscribe-gap

Conversation

@GraemeF

@GraemeF GraemeF commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

The in-memory store lost an event appended after subscribe or subscribeAll returned but before the returned stream started running. The Postgres store had the same gap, fixed in #399.

The cause was Stream.fromPubSub, which subscribes to the PubSub only when the stream runs. Per-stream subscribe also took its history snapshot at subscribe time, so an event appended in the gap was in neither the snapshot nor the live feed.

A live stream now takes its snapshot and subscribes to the PubSub when it runs, both under the lock that append holds while it publishes. The snapshot starts from the position recorded when subscribe was called. EventStore.subscribe takes no Scope, so subscribing eagerly would leave a subscription open for any stream the caller never runs. Doing the work at run time avoids that without changing the public API.

The new tests subscribe, append, and only then run the stream. The fork-based tests added to the Postgres store in #399 pass against the old in-memory code, because the forked fiber subscribes before the append publishes.

…n runs

The in-memory store's subscribe and subscribeAll built their streams on
Stream.fromPubSub, which only subscribes to the PubSub once the stream
runs. An event appended after subscribe returned but before the stream
started was published to nobody. Per-stream subscribe also took its
history snapshot at subscribe time, so an event appended in that gap
was in neither the snapshot nor the live feed.

A live stream now takes its snapshot and subscribes to the PubSub when
it runs, both under the lock that append holds while it publishes. The
snapshot starts from the position recorded when subscribe was called,
so nothing is lost or delivered twice, and a stream that is never run
holds no subscription.

The new tests subscribe, append, and only then run the stream. The
fork-based tests added to the Postgres store pass against the old
in-memory code, because the forked fiber subscribes before the append
publishes.
@sonarqubecloud

Copy link
Copy Markdown

@GraemeF
GraemeF marked this pull request as ready for review September 30, 2026 12:29
@GraemeF
GraemeF merged commit ead2ca2 into main Sep 30, 2026
2 checks passed
@GraemeF
GraemeF deleted the fix/inmemory-subscribe-gap branch September 30, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant