Skip to content

Release v16.16.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 16:23
502c97a

Caution

Known broken packageCratis.Chronicle.Testing in this release bakes in Cratis.Screenplay 1.x types, so consumer specs fail against Screenplay 2.0+ (#3598). Use v16.19.3 or later.

Summary

Defects and missing seams found running Chronicle in a large production application.

Added

  • IEventStore.Registration reports what became of each declared artifact when registration ran, and what stopped the run if it failed, with WaitForRegistration() to await it
  • IProjections.GetStateForModel<TReadModel>() and GetFailedPartitionsForModel<TReadModel>() reach a projection by the read model it maintains, which for a model-bound projection is the only handle there is
  • ReadModelScenario exposes the client artifacts registry, so a spec can ask which artifacts were registered
  • [ReservedProtoFields] keeps retired proto field numbers reserved across regeneration
  • CHR0039 now covers every awaitable and the integration testing surface

Changed

  • A unique constraint violation message no longer includes the offending value; it moved to the violation details, where the application chooses whether to render it
  • Client EventSequenceNumber.Max is now ulong.MaxValue - 1, matching the kernel; code that captured the old value sees it as an ordinary sequence number
  • Subscribing the same handler to IConnectionLifecycle.OnConnected or OnDisconnected twice now subscribes it once; removing is unchanged
  • IEventStore gains a member, so any implementation outside this repository must add it

Fixed

  • The pre-16.12 constraint-store upgrade shipped but never ran, because its serializer was never registered
  • One unregistered event type aborted projection discovery for every projection, taking the whole read side down
  • A projection replay rewrote every stored child whole, defaulting every member the projection did not set
  • Reading a read model turned an absent collection into null instead of an empty one
  • The compliance release pass blanked a value that had never been encrypted
  • A client concurrency scope meaning "no expected sequence number" arrived at the kernel as an ordinary number, so the kernel ran a check that could only pass
  • A skipped concurrency check was attributed to the caller
  • GetStateFor<TProjection>() looked in the read model dictionary with a projection type, so it could only ever throw
  • A failed projection registration named every identifier in the batch instead of the definition that failed
  • A registration that threw left its outcome looking unfinished, so a consumer waiting on it timed out instead of being told what failed
  • Two projections maintaining the same read model resolved silently by declaration order
  • Two dependency injection containers in one process sharing a namespace were handed the same event store
  • Concurrent callers asking for the same event store each built their own and ran discovery twice
  • An event store that could not be reached on its first resolution stayed unreachable for the lifetime of the process
  • CHR0002 demanded [EventType] on generic arguments that are not events
  • CHR0004 and CHR0005 analysed a reactor's private helper methods as if they were handlers
  • CHR0010 counted the absence of [EventStore] as a distinct store, so a single-store projection reported as multi-store
  • CHR0025 reported a collision an event named by [ChildrenFrom] cannot cause
  • The code analysis rule index was missing its CHR0039 row
  • [NoAutoMap] was ignored on [ChildrenFrom] children and [Nested] members, and a nested object used the root's exclusions instead of its own
  • Two [SetFromContext<T>] for the same event type on one member silently discarded all but the last
  • A message: on a property-level [Unique] was silently discarded
  • Three attribute docstrings promised that projections filter on event metadata
  • Cratis.Chronicle.XUnit.Integration omitted the embedded kernel's runtime dependencies from its package
  • A unique constraint definition compared its covered events by reference, so every re-registration looked like a change and asked for a reindex