platform/catalog: generic ProjectionStore[T] consumer + race-free holder; finish C1
- Generic SnapshotWriter[T]/SnapshotReader[T] over a value-agnostic raw layer; SnapshotHolder[T] now RWMutex-guards munmap vs in-flight Get (race-free swap, TestSnapshotHolder_SwapRace) — the drain grace is now just close-batching. - ProjectionStore[T]: snapshot begin|chunk|end assembly → atomic swap, epoch-gated delta overlay, tombstones, atomic epoch sidecar (ordered before the swap), cold-start reopen, mandatory ProjectionTransform[T]. Future-epoch deltas are dropped by contract (recover via next snapshot), not buffered. - Shared bus-framing constants so producer + consumer agree. - Bump slask-finder / go-cart-actor / backoffice pointers; refresh status.md + catalog-projection.md to the finished state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5a3ffcb6bc
commit
8b454bccac
8 files changed
+959
-170
No files matched your search
@@ -148,3 +148,27 @@ func Decode(raw []byte) (Projection, error) {
|
||||
err := json.Unmarshal(raw, &p)
|
||||
return p, err
|
||||
}
|
||||
|
||||
// ── Bus framing contract (shared by producer + consumer) ─────────────────────
|
||||
//
|
||||
// catalog.projection_published carries two channels distinguished only by
|
||||
// event.Event.Meta. The producer (slask-finder writeradmin) sets these keys and
|
||||
// the consumer (ProjectionStore, consumer.go) reads them — one definition so the
|
||||
// two never drift. See docs/catalog-projection.md.
|
||||
//
|
||||
// - A FULL SNAPSHOT is a framed begin → chunk* → end stream, all tagged with one
|
||||
// MetaEpoch. begin/end carry MetaCount (total projections) for completeness
|
||||
// validation; chunks carry the projections.
|
||||
// - A DELTA has NO MetaSnapshotPhase key, and MetaEpoch names the snapshot base
|
||||
// it builds on (consumers ignore a delta older than the base they hold).
|
||||
const (
|
||||
MetaSnapshotPhase = "snapshot" // begin|chunk|end; absent ⇒ delta
|
||||
MetaEpoch = "epoch" // int64 (Unix-ms), monotonic across rebuilds
|
||||
MetaSeq = "seq" // chunk sequence within a snapshot
|
||||
MetaCount = "count" // total projections (begin/end only)
|
||||
MetaTenant = "tenant" // namespace tag
|
||||
|
||||
SnapshotBegin = "begin"
|
||||
SnapshotChunk = "chunk"
|
||||
SnapshotEnd = "end"
|
||||
)
|
||||
Reference in new issue
Block a user