CRITICAL: Rewrite NATS store — use JetStream stream with subjects, not KV #24

Closed
opened 2026-02-19 22:05:43 +00:00 by ash · 1 comment
Owner

Problem

Current natsstore uses KV bucket with ALL events serialized as JSON array per key. Fundamentally broken.

Reference Implementations

  • Rita (Synadia official PoC): /tmp/rita — the gold standard for NATS ES. Study this closely.
  • Myrra transport: /tmp/yoyopass/pkg/myrra/transport/nats/

Rita Design (adopt this)

Subject pattern

$ES.<store>.<entity-type>.<entity-id>.<event-type>

Event type IN the subject = filterable at NATS level without deserializing. Three-token entity: type.id.eventtype.

Stream config

AllowAtomicPublish: true  // NATS 2.12 atomic batch
AllowDirect: true         // Direct get by sequence

Append

  • Single event: js.PublishMsg with headers
  • Multiple events: jetstreamext.PublishMsgBatch (atomic, from orbit.go)
  • OCC: ExpectedLastSubjSeqSubjHeader with entity wildcard pattern

Evolve (read/replay)

  • Ordered ephemeral consumer, catch-up to pending count
  • Filter by subject pattern with wildcards
  • WithAfterSequence for partial replay
  • WithStopSequence for bounded replay

Watch (live subscription)

  • Ordered consumer with async callback
  • Catch-up first, then live
  • Error handler callback
  • NoWait option

Headers (metadata)

  • Rita-Entity, Rita-Type, Rita-Time, Rita-Codec
  • Rita-Meta- prefix for custom metadata
  • We use es- prefix convention instead

What we do BETTER than Rita

  • Generics (Rita uses any everywhere)
  • DCB
  • Single writer CommandBus
  • Encryption + GDPR
  • Multi-tenancy
  • Schema evolution/upcasting
  • Conformance test suite

Dependencies

  • github.com/synadia-io/orbit.go/jetstreamext for atomic batch
  • OR implement our own batch publish with NATS batch headers

Tests

  • Conformance suite passes
  • Atomic batch: multi-event commit
  • OCC with subject sequence
  • Ordered consumer replay
  • Watch with catch-up + live
  • Filter by entity type, entity id, event type, wildcards
  • Integration test on VPS with real NATS
## Problem Current natsstore uses KV bucket with ALL events serialized as JSON array per key. Fundamentally broken. ## Reference Implementations - **Rita** (Synadia official PoC): /tmp/rita — the gold standard for NATS ES. Study this closely. - **Myrra transport**: /tmp/yoyopass/pkg/myrra/transport/nats/ ## Rita Design (adopt this) ### Subject pattern `$ES.<store>.<entity-type>.<entity-id>.<event-type>` Event type IN the subject = filterable at NATS level without deserializing. Three-token entity: `type.id.eventtype`. ### Stream config ```go AllowAtomicPublish: true // NATS 2.12 atomic batch AllowDirect: true // Direct get by sequence ``` ### Append - Single event: `js.PublishMsg` with headers - Multiple events: `jetstreamext.PublishMsgBatch` (atomic, from orbit.go) - OCC: `ExpectedLastSubjSeqSubjHeader` with entity wildcard pattern ### Evolve (read/replay) - Ordered ephemeral consumer, catch-up to pending count - Filter by subject pattern with wildcards - `WithAfterSequence` for partial replay - `WithStopSequence` for bounded replay ### Watch (live subscription) - Ordered consumer with async callback - Catch-up first, then live - Error handler callback - NoWait option ### Headers (metadata) - `Rita-Entity`, `Rita-Type`, `Rita-Time`, `Rita-Codec` - `Rita-Meta-` prefix for custom metadata - We use `es-` prefix convention instead ## What we do BETTER than Rita - Generics (Rita uses `any` everywhere) - DCB - Single writer CommandBus - Encryption + GDPR - Multi-tenancy - Schema evolution/upcasting - Conformance test suite ## Dependencies - `github.com/synadia-io/orbit.go/jetstreamext` for atomic batch - OR implement our own batch publish with NATS batch headers ## Tests - Conformance suite passes - Atomic batch: multi-event commit - OCC with subject sequence - Ordered consumer replay - Watch with catch-up + live - Filter by entity type, entity id, event type, wildcards - Integration test on VPS with real NATS
Author
Owner

NATS store rewritten from KV to proper JetStream stream with subject-per-entity, atomic batch support, ordered consumers, OCC via ExpectedLastSubjectSequence. 31/32 conformance tests passing.

NATS store rewritten from KV to proper JetStream stream with subject-per-entity, atomic batch support, ordered consumers, OCC via ExpectedLastSubjectSequence. 31/32 conformance tests passing.
ash closed this issue 2026-02-20 00:32:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ash/eskit#24
No description provided.