This document discusses an event sourcing framework called Concursus. It begins with an introduction and agenda. It then covers moving from centralized to distributed systems using event sourcing, writing events first before processing them, three types of event processing schedules, the Concursus framework itself, and future directions for Concursus including stable Kafka integration and an asynchronous programming model.
3. Agenda
1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
4. Agenda
1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
5. Agenda
1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
6. Agenda
1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
7. 1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
Agenda
8. 1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
Agenda
9. "I have told people over and over and over again, don't write a
CQRS framework…I can basically guarantee you that it will be
abandonware within one year, like every other one has become.”
- Greg Young, inventor of the term “CQRS”
Why Concursus?
10. Agenda
1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions
12. From Presence to Presents
Aggregate services together into a single container or integrate
them through a single enterprise service bus...
Manage all of our data through a single relational database
schema with global constraints...
Use distributed locks and transactions to make a distributed
system behave as if it were one single system with a global
transactional semantics...
16. From Presence to Presents
“Here the Microservice can become an escape route from reality. Within each Microservice, we can
live on a safe island of determinism and strong consistency — an island where we can live happily
under the illusion that time and the present is absolute.
However, as soon as we exit the boundary of the Microservice we enter a wild ocean of non-
determinism—the world of distributed systems, which is a very different world. You have probably
heard that building distributed systems is hard. It is. That being said it is also the world that gives
us solutions for resilience, elasticity, isolation amongst others. At this point, what we need to do is
not to run back to the monolith, but instead learn how to apply and use the right set of principles,
abstractions and tools in order to manage it.”
- Jonas Bonér, Reactive Microservices Architecture, p. 28-29
34. Domain Model: Summary
Every Event occurs to an Aggregate, identified by its type and id.
Every Event has an eventTimestamp, generated by the source of
the event.
An Event History is a log of Events, ordered by
eventTimestamp, with an additional processingTimestamp
which records when the Event was captured.
41. Processing Model: Summary
Events arrive partitioned, interleaved and out-of-order.
Events are sorted into event histories by aggregate type and id.
Events are sorted within event histories by event timestamp, not
processing timestamp.
Event consumers need to take into account the possibility that an
event history may be incomplete at the time it is read – consider
using a watermark to give incoming events time to “settle”.
46. Event-handling middleware is a chain of Consumer<Event>s that transforms, routes,
persists and dispatches events. A single event submitted to this chain may be:
■ Serialised to JSON
■ Written to a message queue topic
■ Retrieved from the topic and deserialised
■ Persisted to an event store (e.g. Cassandra)
■ Published to an event handler which maintains a query-optimised view of part of the
system
■ Published to an event handler which maintains an index of aggregates by event property
values (e.g. lightbulbs by wattage)
Event-Handling Middleware
55. ■ Event type and middleware implementing Consumer<Event>
provide basic mechanics for creating, processing and handling events.
■ Java 8 mappings provide a convenient, type-safe method-mapping
wrapper around these mechanisms.
■ Kotlin mappings provide an alternative wrapper based on immutable
classes.
■ Other mappings are possible – Scala, Clojure, Java with POJOs…
Programming Model: Summary
56. Agenda
1. From Presence to Presents
2. “Write First, Reason Later”
3. Three processing schedules
4. Concursus
5. Future Directions