Repository navigation
Replace decision model builder with a Decision - #937
Merged
Merged
Conversation
A Decision collects everything a command reads and appends the new events with a matching append condition, so handlers no longer pass the condition around. Reads can depend on earlier reads (chained reads), and an array of projections is still read with a single query. The append condition now uses the head of the store at the first read as `after` instead of the last matching event. With the last matching event, combining several reads either blocks every append or misses concurrent changes of the first read. Command handlers get a new Decision per dispatch as second argument when the command bus is configured with the DecisionParameterResolver, which the container does if dcb is enabled.
|
Hello 👋 here is the most recent benchmark result:
This comment gets update everytime a new commit comes in! |
DanielBadura
approved these changes
Oct 16, 2026
DavidBadura
added a commit
to patchlevel/event-sourcing-phpstan-extension
that referenced
this pull request
Oct 18, 2026
patchlevel/event-sourcing#937 added the Decision for the dynamic consistency boundary. Reading an array of projections now becomes an array shape with the state type of each projection, a single projection its state type. The state type is taken from the projection generic and falls back to the return type of initialState(). ProjectionBuilder::build() is typed the same way again, it was dropped together with the other DCB parts while they only existed in 4.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Handlers now get a
Decisionthat remembers everything they read and appends the new events with the matching append condition, so nobody has to pass$state->appendConditionaround anymore.read()takes a single projection (typed via the projection generic, no phpstan extension needed) or an array of projections, which are read with one query likebuild()did before. Reads can depend on earlier reads, so chained reads like "students of a course, then the courses of each student" are just anotherread().To make that safe,
afteris now the head of the store at the first read instead of the last matching event. With the last matching event, combining reads either blocks every append (a later read saw newer events) or misses concurrent changes of the first read. This needs a newAppendStore::head().The command bus resolves the
Decisionargument through a new optionalParameterResolveronServiceHandlerProvider, the container wires it whendcbis enabled. Without our command bus,DecisionFactory::begin()starts a decision.DecisionModelBuilder,StoreDecisionModelBuilderandDecisionModelare removed.On Postgres the array form is as fast as before (about 9 ms for five projections). Single reads cost one query each plus one
MAX(id)per decision. The phpstan extension needs an update to type the array form as a shape.