CHR0009: Reducer event types must be from the same event store
Rule Description
Section titled “Rule Description”A reducer subscribes to one event store’s event stream. Reducing events from multiple event stores would require multiple subscriptions, which Chronicle does not support for a single reducer. Ensure all event types in this reducer are from the same event store, or split it into separate reducers—one per event store.
Severity
Section titled “Severity”Error
Example
Section titled “Example”Violation
Section titled “Violation”using Cratis.Chronicle.Events;using Cratis.Chronicle.Reducers;
public record Chr0009ViolationBookStatus(string Title, bool IsAvailable);
[EventType("book-added")][EventStore("library")]public record Chr0009ViolationBookAdded(string Title);
[EventType("book-borrowed")][EventStore("rentals")]public record Chr0009ViolationBookBorrowed(string Title);
// Error CHR0009: Reducer 'Chr0009ViolationBookStatusReducer' reduces event types from// multiple event stores: "library", "rentals". All event types in a reducer must// originate from the same event store.public class Chr0009ViolationBookStatusReducer : IReducerFor<Chr0009ViolationBookStatus>{ public Chr0009ViolationBookStatus Reduce(Chr0009ViolationBookAdded @event, Chr0009ViolationBookStatus? current, EventContext context) => new(@event.Title, true);
public Chr0009ViolationBookStatus Reduce(Chr0009ViolationBookBorrowed @event, Chr0009ViolationBookStatus? current, EventContext context) => current is null ? new(string.Empty, false) : current with { IsAvailable = false };}using Cratis.Chronicle.Events;using Cratis.Chronicle.Reducers;
public record Chr0009FixBookStatus(string Title, bool IsAvailable);
[EventType("book-added")][EventStore("library")]public record Chr0009FixBookAdded(string Title);
[EventType("book-borrowed")][EventStore("library")]public record Chr0009FixBookBorrowed(string Title);
// All event types belong to the same event store: "library".public class Chr0009FixBookStatusReducer : IReducerFor<Chr0009FixBookStatus>{ public Chr0009FixBookStatus Reduce(Chr0009FixBookAdded @event, Chr0009FixBookStatus? current, EventContext context) => new(@event.Title, true);
public Chr0009FixBookStatus Reduce(Chr0009FixBookBorrowed @event, Chr0009FixBookStatus? current, EventContext context) => current is null ? new(string.Empty, false) : current with { IsAvailable = false };}Why This Rule Exists
Section titled “Why This Rule Exists”Chronicle routes events from a single event store to each observer. A reducer that declares handlers for events from different stores would require Chronicle to multiplex subscriptions, which the observer model does not support. This rule catches the misconfiguration at compile time instead of failing when the client connects.
Split reducers that genuinely need to reduce events from different stores into one reducer per store, each subscribing to its own event stream.
Related Rules
Section titled “Related Rules”- CHR0008: Reactor event types must be from the same event store — the same contract for reactors.
- CHR0010: Model-bound projection event types must be from the same event store — the same contract for model-bound projections.
- CHR0011: Declarative projection event types must be from the same event store — the same contract for fluent projections.