Dynamic Consistency Boundary in Chronicle
Chronicle was designed to support decision-scoped consistency long before DCB was named. You can append events independently, project read models from disparate streams, and still enforce consistency for the specific facts used to decide.
Mapping DCB to Chronicle
- Decision facts are read from projections or other read models.
- Constraints validate that the decision is still valid when appending events.
- Concurrency scopes let you define which streams or partitions must be checked together.
- Projections update read models asynchronously after the append.
flowchart LR
A[Client command] --> B[Read models]
B --> C[Decide and build constraints]
C --> D[Append events]
D --> E[Event store]
D --> F[Projections]
F --> B
C --> G[Concurrency scopes]
G --> D
Constraints and concurrency scopes
Constraints are the primary way to express decision correctness. They are evaluated at append time, so the decision is validated against the most recent events. Concurrency scopes complement this by defining which streams must be checked together to keep the decision consistent without forcing a single aggregate boundary.
Metadata tags
Chronicle uses formalized metadata tags to scope concurrency control. These tags are indexed and used by Chronicle when evaluating concurrency scopes:
- EventSourceId: Unique identifier for the event source
- EventSourceType: Overarching, binding concept (e.g., Account)
- EventStreamType: A concrete process related to event source type (e.g., Onboarding, Transactions)
- EventStreamId: A marker to separate independent streams for a stream type (e.g., Monthly, Yearly)
- EventTypes: Specific event types to scope concurrency to
For more details, see Formalized metadata tags for concurrency.
You can also attach custom tags to events when appending for categorization and filtering purposes.
Aggregate roots
If you prefer an aggregate root style, Chronicle supports it through Cratis.Arc. See aggregate roots support.
Arc command validation flow
When using Arc, command validation runs before decision evaluation. See Arc validation for details.
flowchart LR
A[Client command] --> B[Arc command validation]
B --> C[Read models]
C --> D[Decide and build constraints]
D --> E[Append events]
E --> F[Event store]
E --> G[Projections]
G --> C
D --> H[Concurrency scopes]
H --> E
Practical flow
- Read the projections needed to decide.
- Build constraints that capture the decision rule.
- Choose concurrency scopes that match the decision boundary.
- Append events and let projections update.