Repository navigation
Release v22.63.0
Commands can now say which stream they decide on, guard exactly that stream, close it, and tag what they append, without injecting the event log.
Added
[EventStreamId("{ReportingScopeId}:{Period}")]builds a command's stream id from its own properties, so owner-qualified ids no longer needICanProvideEventStreamId. Concepts contribute their underlying value, dates and times use fixed invariant formats, and the id is resolved after validation, so a validator can reject a missing part.EventStreamIdTemplate.ResolveFor(command)returns the same id for reads and seeding. See Concurrency. (#3102)EventRoutecarries the source type, stream type and stream id of a route. Resolve it from an event source definition withIEventRoutes.For<TSource>(stream), read the command's own route withCommandContext.GetEventRoute(), and stamp returned events withroute.Route(id, events), so command metadata, reads and appends use one value. (part of #2987)IStreamReadsreads one stream, or every stream of one stream type, for an event source, tail first. The returnedStreamDecision.Append(...)appends routed events guarded at that tail. An empty stream is checked as a first append, and a concurrent append into the same stream comes back as a concurrency validation failure. See Stream decisions. (#3101)- Return
CompleteStreamfrom a command handler, alone or next to its events, to close a stream after the command's events commit. Reactors can return it too. An already completed stream counts as success, and a later append to the closed stream is a validation failure. Closing happens after the commit, not atomically with it. See Completing streams. (#3091) - Commands can tag the events they append with structured named tags:
[EventTag("projectId", nameof(ProjectId))],ICanProvideEventTags, a returnedEventTagsvalue, or application-wideICanProvideCommandEventTagsproviders. Tags on returnedEventForEventSourceIdwrappers are kept on every append path. See Event tags. (#2570) CommandScenariocan seed events on a route (Given.ForEventSource(id).OnRoute(route).Events(...)), append competing events on a route (AppendConcurrently(id, route, events)), and assert closed streams withShouldHaveCompletedStream(...).- Analyzer ARCCHR0016 warns when a command declares
concurrency: truebutHandlereturnsEventsWithConcurrencyScopes, whose exact scopes replace the attribute's. A code fix removes the flag. (#3100) - Analyzer ARCCHR0017 reports an
[EventStreamId]template that names a missing, non-public or non-convertible property, or has malformed braces. ARCCHR0018 warns when a template is put on a reactor, where Chronicle uses the value literally. (part of #3102)
Changed
- ARCCHR0011 and ARCCHR0012 now point to stream decisions as the guarded alternative. ARCCHR0003 and ARCCHR0007 point to returning
CompleteStreamwhen the code closes a stream through the event log. - Screenplay analysis reports a template stream id as derived from command properties instead of a fixed stream id.
- The concurrency and events documentation states that
EventsWithConcurrencyScopesreplaces scopes derived from attributes and event source definitions. (part of #3100)