Ron Stevenson
Ron Stevenson

Reputation: 166

event sourcing relationships and basics

I work for a startup and we're hoping to build a basic proof of concept with event sourcing. Can anyone provide some clarification on these basic questions?

  1. Is an event source a collection of event streams?
  2. Would you have an event source per bounded context? Or maybe per DDD Aggregate(like for a car and its changes)?
  3. Would each event source have its own data store?
  4. Would an example be an event source of a car, where each event stream is based on a unique carId?

Question on a possible basic flow...does this sound complete and make sense?

client --> eventStore API --> store the event --> maybe publish a message to a queue --> Ack to client giving a thumbs up --> go build your read models/indexes? --> client publishes the event publicly --> other consumers of that same event now can take action based on the event.

I'm not totally clear on the "build read models" part...I guess you could go build "projections" in any separate data store? Or just index the data in the actual event store for fast querying?

Any clarification on these questions would be great.

Thanks! -Ron

Upvotes: 0

Views: 1157

Answers (1)

Constantin Galbenu
Constantin Galbenu

Reputation: 17693

I will give you some basic Event sourcing terms that I've-used/seen-used. Also, I will use Event sourcing in the context of CQRS, although it can be used separately (I didn't do it until now).

The Event store is the persistence (the database) of the events. The write/command and the read/query sides of the application have different requirements regarding the Event store.

The write side needs that the events emitted by an Aggregate must be in order and protected from concurrent insertions. People call this an Event stream = all the events emitted by an Aggregate instance (i.e. Product#1234). The Event stream should also be fast when reading, that is, reading all the events from the Event stream in the order they were emitted, the oldest first, should be very fast; this is needed for Aggregate rehydration, before executing every command.

The read side would like all the events to be in a total order, across all Aggregates. If you afford this requirement then the Readmodels are simpler to construct. However, with a greater development+design effort, it is possible to create Readmodels that do not require total order.

The problem with big systems is that, in general, the Readmodels need events from multiple Event stores

Is an event source a collection of event streams?

If by "event source" you mean "Event store", then YES.

Would you have an event source per bounded context? Or maybe per DDD Aggregate(like for a car and its changes)?

The simplest system is the one with a single Event store instance. This is because the Readmodels then need to connect to only one instance, and you can have a total order of events.

If the system is too big, having a single Event store is not possible. This means that you cannot have a total order of events which means that the Readmodels are harder to construct (not impossible) and the operational costs increase.

So, you must make a tradeoff. One nice tradeoff is to have an Event store per bounded context.

Would each event source have its own data store?

This question does not make sense in the context of this answer. One Event store = one data store.

Would an example be an event source of a car, where each event stream is based on a unique carId?

Yes, each car instance (having an unique ID) has an event stream.

client --> eventStore API --> store the event --> maybe publish a message to a queue --> Ack to client giving a thumbs up --> go build your read models/indexes? --> client publishes the event publicly --> other consumers of that same event now can take action based on the event.

It depends on your architecture/style/how the Readmodels receive the events.

You may have a simple synchronous system, when, in the same process/thread, a command is processed, events are emitted, they are immediately persisted to the event store, then all the Readmodels and Sagas are fed with these new events, all done synchronous, one after another.

A more complex system executes the command, persists the events to the Event store, then returns the response to the client. In a separate process, the Readmodels and the Sagas poll the new events from the Event store (which provides such an API) and processed them in the background.

Other solutions use message queues; this is somewhat hard to do because one cannot safely-and-in-a-scalable-way persist the events to the Event store and publish them to the message queue, in an atomic way (both succeed or none).

Upvotes: 3

Related Questions