DCB Examples #299
Replies: 11 comments 3 replies
-
You linked to the general website before, but it might be more clear to specify that this follows the distinct specification laid out by dcb.events. I was also considering whether a simple ER diagram may be helpful here. erDiagram
Query ||--o{ QueryItem : contains
QueryItem ||--o{ Type : contains
QueryItem ||--o{ Tag : contains
Query {
int after
}
QueryItem {
}
Another way to formulate what you have written is that query items are combined by logical ORs, i.e., an event is selected if any of them matches. For one specific query item, the types are combined by logical ORs but the tags by logical ANDs. |
Beta Was this translation helpful? Give feedback.
-
I was wondering if command handler would be a better word, since method has a specific meaning. |
Beta Was this translation helpful? Give feedback.
-
I would guess that in 99% of cases, the append condition is indeed the same query, but it doesn't have to be. |
Beta Was this translation helpful? Give feedback.
-
I agree that this example can be solved by appending an event to each aggregate's stream. And that also makes a lot of sense to me. I don't fully follow the obsession to record the fact of a student joining a course by a single event only. Having said that, I do see that the option to select events from "multiple streams" in a single query is interesting. (In reality there is only one global stream when using DCB, but that is my mental image in the non-DCB paradigm.) |
Beta Was this translation helpful? Give feedback.
-
I don't have exact sources readily available, but I read in multiple places that an aggregate protects the consistency of its own state. |
Beta Was this translation helpful? Give feedback.
-
# Append using the same consistency boundary as the fail condition.
self.recorder.append(
events=[student_joined_course],
condition=DCBAppendCondition(
fail_if_events_match=consistency_boundary,
after=head,
),
)I have a feeling that it should be possible to implement a smart retry mechanism, where events matched by the append condition are directly added to the sequence of events to build the state for the decision model. |
Beta Was this translation helpful? Give feedback.
-
|
My only comment to DCB 3 is essentially what you write here:
You have basically abandoned the event types selection from the queries, which makes sense when hydrating whole aggregates. Indexing definitely seems like a promising approach. Indeed, I've seen talk of not using explicit tags, but instead allowing indexing of any event property. I haven't seen an implementation for such a system yet, though. |
Beta Was this translation helpful? Give feedback.
-
def do(self, s: TSlice) -> TSlice:
s = self.repository.project_perspective(s)
s.execute()
if s.new_decisions:
self.repository.save(s)
return sI'm curious about the decision that |
Beta Was this translation helpful? Give feedback.
-
|
https://eventsourcing.readthedocs.io/en/latest/topics/examples/coursebooking-dcb-slices.html#slices class UpdateStudentName(Slice):
def __init__(self, student_id: StudentID, name: str) -> None:
self.id = student_id
self.name = name
self.student_was_registered: bool = False
@property
def cb(self) -> Selector:
return Selector(types=[StudentRegistered, StudentNameUpdated], tags=[self.id])
@event(StudentRegistered)
def _(self) -> None:
self.student_was_registered = True
def execute(self) -> None:
assert self.student_was_registered
self.append(StudentNameUpdated(tags=[self.id], name=self.name))I know, this is just an example, but since you already select |
Beta Was this translation helpful? Give feedback.
-
|
https://eventsourcing.readthedocs.io/en/latest/topics/examples/coursebooking-dcb-slices.html#slices Although I really enjoy the vertical slice example using DCB (as you can imagine), this query basically shows that I might as well have two projections built from events of separate event streams, one for the student and one for the course. The only differences being that I'd need two trips to the event store and append two events, one to each stream, as was done in the DCB 1 example. @property
def cb(self) -> list[Selector]:
return [
Selector(
types=[
StudentRegistered,
StudentMaxCoursesUpdated,
StudentJoinedCourse,
StudentLeftCourse,
],
tags=[self.student_id],
),
Selector(
types=[
CourseRegistered,
CoursePlacesUpdated,
StudentJoinedCourse,
StudentLeftCourse,
],
tags=[self.course_id],
),
] |
Beta Was this translation helpful? Give feedback.
-
|
Did you create a speedrun for https://eventsourcing.readthedocs.io/en/latest/topics/examples/coursebooking-dcb-slices.html#dcb-4-enrolment-slices? I'm curious if there is any noticeable difference to DCB 3? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
In the following is my feedback to the DCB examples.
Beta Was this translation helpful? Give feedback.
All reactions