feat(entity,pekko): carry the journal coordinate into view processors #45
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
iterative-works/support!45
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/projection-event-coordinate"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
A projection handler receives the event's journal position —
persistenceIdandsequenceNr— andthrows it away before calling the view processor:
A read model therefore has no stable, unique identity to key its records on. Downstream
(MEDECA-447) that shows up as two Mongo timeline collections that insert a duplicate document on
every projection replay, because the only identity available to them —
userId|epochSecond— isneither stable nor unique per event. Measured in a dev database: 597 journal events, 5933 documents.
The journal coordinate is the right identity: assigned at write time, unchanged by replay, unique
per event, and unaffected by event-schema changes. It was already in scope at the handler; it just
had nowhere to go.
What
EventCoordinate(persistenceId, sequenceNr)andCoordinatedViewProcessor— both inentity/shared, so cross-compiled view processors can implement them.PekkoProjectionSupport.runSingleCoordinatedplusCoordinatedProjectionHandler, which reads thecoordinate off the envelope.
runSinglere-expressed overrunSingleCoordinatedviaCoordinatedViewProcessor.lift, so thereis one projection-wiring implementation instead of two near-identical bodies.
Additive by construction
No existing public signature changes and no existing call site needs editing.
ViewProcessor,ProjectionHandlerandrunSinglekeep their exact shapes —ViewProcessor.scalaand
ProjectionHandler's body are byte-for-byte identical tov0.1.22. No deprecations, no compatshims. Existing consumers are unaffected whether or not they ever adopt the new entry point.
Base branch
Targets
release/0.1.x, cut fromv0.1.22— notmain.mainhas moved to0.2.2-SNAPSHOT,including a
Momentrewrite (opaque type Moment = Instantincorebecameopaque type Moment = Longin a newtimemodule). The consuming project pins0.1.22, andabsorbing the
0.2.xmigration is a much larger piece of work than the bug this unblocks. Thislands as
0.1.23off the maintenance line; a forward-port tomainfollows separately.Tests
entityandpekko-persistencehad no test sources; both now have a test module, wired to theexisting
BaseTestspattern.CoordinatedViewProcessorSpec—liftforwards the event and discards the coordinate, against aRef-backed stand-in rather than a mock.CoordinatedProjectionHandlerSpec—coordinateOfmaps an envelope to its journal position:events sharing a
persistenceIdare told apart bysequenceNr, events sharing asequenceNrbypersistenceId, a replayed position yields an equal coordinate, and the payload does not affectidentity. That last pair is exactly the replay-idempotence and data-loss behaviour downstream
depends on.
Verified:
./mill __.test2218/2218,./mill __.checkFormatclean,entity.js.compilepasses(the shared placement really is cross-compiled). The tests were mutation-checked — pointing
coordinateOfatenvelope.timestampinstead ofsequenceNrfails 2 of them; reverted.🤖 Generated with Claude Code