Skip to content

Commit

Permalink
Merge pull request #124 from dogmatiq/113-apply-historical
Browse files Browse the repository at this point in the history
Allow engine to call `ApplyEvent()` with historical events.
  • Loading branch information
jmalloc authored Oct 19, 2020
2 parents 369db92 + dfd08fb commit b800541
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
13 changes: 9 additions & 4 deletions aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,16 @@ type AggregateRoot interface {
// ApplyEvent updates the aggregate instance to reflect the occurrence of an
// event that was recorded against this instance.
//
// It MUST NOT be called with a message of any type that has not been
// configured for production by a prior call to Configure().
// The engine MUST call ApplyEvent() for each newly recorded event. It MAY
// call ApplyEvent() with any event that has already been recorded against
// this instance, even if that event type is no longer configured for
// production by a prior call to Configure().
//
// The implementation MUST accept the event types as described above, though
// any such call MAY be a no-op.
//
// It MUST accept all messages of the types that have been configured for
// production, though any given call MAY be a no-op.
// The implementation MUST panic with the UnexpectedMessage value if called
// with any event type other than those described above.
ApplyEvent(m Message)
}

Expand Down
40 changes: 40 additions & 0 deletions docs/adr/0014-apply-historical-events-to-aggregates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 14. Applying Historical Events to Aggregate Instances

Date: 2020-10-19

## Status

Accepted

## Context

Event sourcing engines need to call `AggregateRoot.ApplyEvent()` with
"historical" event types. That is, event types that have already been recorded
against the instance but are no longer configured for production by that
aggregate.

The current specification language prohibits this, as per the `ApplyEvent()`
documentation:

> It MUST NOT be called with a message of any type that has not been
> configured for production by a prior call to Configure().
Additionally, without adding some new features to `AggregateConfigurer` it is
impossible to declare an event as historical, meaning that there is no way to
discover historical event types from the configuration.

## Decision

We have chosen to relax the language in the specification to allow calling
`ApplyEvent()` with any historical event types in addition to those configured
for production.

## Consequences

Existing event sourcing engine implementations are no longer violating the spec.

As this is a documentation change only it does not provide engines with any
information they need to determine if an event type is historical. This should
be a non-issue as the engine itself will have its own mechanism for loading
historical events. We may expand the functionality of `AggregateConfigurer` in
the future to allow declaration of historical event types.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ the ADR documents.
* [11. Message Timing Information](0011-message-timing-information.md)
* [12. Comparison of Identifiers](0012-identifier-comparison.md)
* [13. Aggregate and Process Instance Existance Checks](0013-instance-exists-check.md)
* [14. Applying Historical Events to Aggregate Instances](0014-apply-historical-events-to-aggregates.md)

0 comments on commit b800541

Please sign in to comment.