Consumer side of the catalog-projection seam (C1): - catalogProjectionCache now wraps ProjectionStore[catalog.Projection] (identity transform — the cart's overlay uses ~all fields); delivery handler routes bus frames via HandleFrame (snapshot begin|chunk|end + epoch-stamped deltas). - Per-pod cold-start-ready .bin under CART_PROJECTION_DIR (pod-local, never shared) + IsDeleted tombstone passthrough; HTTP fetch demoted to last-resort. - Tests: test-only Apply shim + mustCache helper keep existing cases green; new snapshot-framing integration test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
40 lines
1.2 KiB
Go
40 lines
1.2 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.k6n.net/mats/platform/catalog"
|
|
)
|
|
|
|
// mustCache opens a per-pod projection cache backed by a temp dir (pod-local).
|
|
func mustCache(t *testing.T) *catalogProjectionCache {
|
|
t.Helper()
|
|
c, err := newCatalogProjectionCache(t.TempDir())
|
|
if err != nil {
|
|
t.Fatalf("newCatalogProjectionCache: %v", err)
|
|
}
|
|
t.Cleanup(func() { _ = c.store.Close() })
|
|
return c
|
|
}
|
|
|
|
// Apply is a TEST-ONLY convenience that routes a delta batch through the store at
|
|
// the initial epoch (0), reproducing the pre-ProjectionStore cache API so the
|
|
// existing cart tests keep exercising Get/IsDeleted/Len. Production code feeds the
|
|
// store via HandleFrame with real bus framing (snapshot + epoch-stamped deltas).
|
|
func (c *catalogProjectionCache) Apply(updates []catalog.ProjectionUpdate) (upserts, deletes int) {
|
|
for _, u := range updates {
|
|
if u.Deleted {
|
|
deletes++
|
|
} else if u.SKU != "" {
|
|
upserts++
|
|
}
|
|
}
|
|
payload, err := catalog.EncodeUpdates(updates)
|
|
if err != nil {
|
|
return 0, 0
|
|
}
|
|
// No MetaSnapshotPhase ⇒ delta; epoch 0 matches a fresh store's base epoch.
|
|
_ = c.store.HandleFrame(map[string]string{catalog.MetaEpoch: "0"}, payload)
|
|
return upserts, deletes
|
|
}
|