Repository navigation
Release v19.11.0
Summary
This PR consolidates the open PRs listed at the end, plus several fixes that had no PR of their own, into one release. The main themes are reactor side-effect reliability, projection and read-model correctness, batch-append fidelity, and erasing more data when an event is redacted. The CI change in #4237 was merged separately and is not part of this PR.
Added
- Register a .NET reactor at runtime by stable ID, explicit event types and generations, and an awaited delegate that receives the event context, the JSON content and the generational content map. Unregister it by ID; the observer keeps its stored position. Tags and filters are not yet configurable on delegate reactors (#4196)
- Reactor side-effect handlers can claim synchronous return types with
CanHandleReturnType(Type), including a declaredIEnumerable<T>. Existing handlers stay compatible (#4121) IReactors.RetryFailedPartitionFor<TReactor>(partition)retries a reactor's failed partition from the .NET client and returns aReactorPartitionRetryOutcome(#3909)- Batch event payloads accept an optional per-event
causationfield. Older kernels ignore it and store only the ambient chain (#4179) - Append results expose the event types the operation wrote, including for batch appends (#4132)
Changed
- A reactor whose return value no side-effect handler claims now fails its partition, naming the return type, instead of logging a warning and acknowledging the event. Fix the handler, then retry the partition (#4156)
- Duplicate reactor IDs, across discovered classes and runtime delegates, are rejected before existing subscriptions disconnect, and the error names both types. A duplicate
Register<T>()now throwsReactorAlreadyRegisteredinstead ofArgumentException(#4196) - A
WaitForCompletion()timeout returns a result withTimedOutset instead of throwing a gRPC cancellation. Supported servers also report which observers are still behind (#4132) - Read-model instance pages from MongoDB, SQL and in-memory sinks are ordered by key, so reading a page again returns the same instances while membership is unchanged (#3741)
- A dynamic dictionary key that uses an unknown
$expression fails withUnsupportedDynamicPropertyPathExpressioninstead of being written as a literal key (#4119) - SQL redaction content describes the original event (type, occurrence time, correlation id, caused-by identities and causation types) instead of the redaction itself, matching the other providers (#4145)
Cratis.Chronicle.Testingdepends onCratis.ArcandCratis.Arc.Core22.19.1 or later, which brings in the ASP.NET Core shared framework. Projects pinned to an older Arc must upgrade (#4158)- Aspire uses the development Chronicle image in run mode and the production image in publish mode. A configuration callback no longer implies the production image;
WithImageTagstill overrides (#3686)
Fixed
- Observer tail lookups and in-process reactor scenarios recognize claimed synchronous reactor return types. Before, such a reactor could silently never fire for that event (#4121)
- Reactors returning events complete in standalone hosts configured with
AddCratisChronicle, and loaded but unconfigured integrations no longer block return-value processing. A configuration failure can no longer cause duplicate appends on retry (#4107) - A failed catch-up job start now quarantines the observer. Before, a returned failure was ignored and the recovery work was lost (#3777)
- A successful replay clears the failed-partition records it covered, so failed-partition monitoring returns to healthy. Failures the replay did not cover, and failures recorded after it started, stay recorded (#4148)
$causedBy,$causedBy(subject),$causedBy(name)and$causedBy(userName)resolve at runtime in projection values and dynamic dictionary keys. Before, they compiled but failed when the projection ran (#4119)- A first-level child event that arrives before its root now resolves when the root is created during live processing, giving the same state as a replay (#4182)
AppendManystores every migrated generation of each event, so consumers of newer and older generations receive the correct content (#4190)AppendManyand unit-of-work commits keep each event's explicit cause after the ambient chain without carrying it into other events (#4179)- With the .NET client and an updated server,
WaitForCompletion()waits only for observers affected by the appended event types. Observers subscribed to all events are still included. On older servers, mixed-type batches can still time out (#4132) Materialized.ObserveInstances<T>()on PostgreSQL and SQLite delivers the initial page and later updates instead of ending with an opaque error. Several writes between polls can arrive as one update, and failures name the sink, read model and container (#4120)- SQL storage updates the stored content hash when an event is revised. Before, the original hash remained (#3820)
- CHR0001 no longer treats tags or concurrency-scope arguments as event types, now reports unmarked events passed by name or in an array to
AppendMany, and its code fix works for named arguments (#4144) - CHR0028 reports only
.AutoMap()calls that are certainly redundant, and no longer flags a call that re-enables AutoMap after.NoAutoMap()or on a[NoAutoMap]read model (#4205) - Projects that reference only
Cratis.Chronicle.Testingcan run event, read-model and reactor scenarios without adding Arc packages themselves (#4158) - In-process testing scenarios return the appended generation's content and generational content for events with migrations (#4190)
ReadModelScenarioretries a child whose parent arrives later instead of dropping it. A parent that never arrives raises the same descriptive error as an unresolved root key (#3700)
Security
- Redacting an event no longer keeps the original causation property values, which can carry command input such as personal data. MongoDB, SQL and in-memory storage store the same redaction content, without property values (#4145)
- Redaction removes the event's revision history and stored content hashes. Before, a revised event that was later redacted kept its revisions, and MongoDB served the revised payload instead of the redaction marker. Redaction does not reach backups, oplogs or events already forwarded to other event stores (#4145)
- The Workbench's
js-yamldependency is updated to 3.15.2, which limits CPU usage from merge sequences (#4012)
Absorbed pull requests: #4191, #4194, #4185, #4233, #4187, #4188, #4210, #4218, #4217, #4193, #4215, #4232, #4229, #4234, #4235, #4012.
Not included, because their owners ship them separately: #4023, #4157, #4152, #4111 and #4146 (in #4250), #4159 (catch-up, held for compatibility work), and #4166 (in #4247). #4162 and #4163 shipped separately in #4242 and #4245.