DEV Community

Cover image for Implementing Domain Driven Design - Event Driven Architecture
DevByJESUS
DevByJESUS

Posted on

Implementing Domain Driven Design - Event Driven Architecture

We continue our series in the chapter 4 about Architecture 😁
Today we will talk about Event Driven Architecture ( EDA )

A. Definition

In a simple way :

Event-driven architecture (EDA) is a software architecture promoting the production, detection, consumption of, and reaction to events.

B. What kind of events ?

Of course in a system with can handle many types of events, but perhaps we are in DDD, the main focus will be on Domain Events , and in the book :

There may be a number of different kinds of events that enter and exit a hexagon. We are interested specifically in Domain Events. The application may also subscribe to system, enterprise, or other types of events as well. Perhaps those deal with system health and monitoring, logging, dynamic provisioning, and the like. Yet, it is the Domain Events that convey the happenings requiring our modeling attention.

N.B: The flow of events will go from one output port to an input port.

flow of events

The Domain Events published by one such system through the output Port would be delivered to subscribers represented in the others through their input Port. The various Domain Events received have a specific meaning in each receiving

C. Pipes and Filters

In EDA there is the concepts of Pipes and Filters , it is important to grasp some characteristics of them , but the main point can be truly understood in the definition

C.1. Filters

A Filter has many characteristics , like the book says :

Filters may process messages without actually filtering. Futhermore Filters receive messages on an inbound Pipe and send messages on an outbound Pipe. Finally Filters connect to inbound and outbound Pipes through a Port. Ports make Hexagonal (Ports and Adapters) a fitting overarching style.

The table below for me explains some key characteristics of filter :

filter characteristics

C.2. Pipes

It is a channel where the event goes after the processing in the filter

The Pipe is actually a message channel

N.B: Understand, however, that a messaging Pipes and Filters approach is not exactly like the command-line version, and it is not intended to be. For example, an EDA Filter doesn’t need to actually filter anything. A Filter in an EDA may be used to perform some processing while leaving the message data intact.

pipeline of events

Here for example PhoneNumberFinder or MatchedPhoneNumberCounter are Filters !

D. How does it fit in DDD?

I thought also it was so simple but it so well said in the book :

In an actual DDD scenario, Domain Events reflect names meaningful to the business. Step 1 could publish a Domain Event based on the behavioral outcome of an Aggregate in one Bounded Context. Steps 2 through 4 could occur in one or more different Bounded Contexts that receive the initial Event and then publish one of the subsequent ones. Those three steps could create or modify Aggregates in their respective Contexts. It does depend on the domain, but those are common outcomes of handling Domain Events in a Pipes and Filters Architecture. Domain Events They explicitly model business process activity occurrences that are useful for domain-wide subscribers to know about, and they pack unique identity and as many knowledge-conveying properties as necessary to clearly get their point across. Yet this synchronous, step-by-step style can be extended to accomplish more than one thing at the same time.

E. Sagas

Of course because we are in the domain of computer we can have events that processes shortly and long running processes because they can be completed after some days and those ones are called Sagas

The synthetic Pipes and Filters example can be extended to demonstrate another Event-Driven, distributed, parallel processing pattern, namely, Long-Running Processes. A Long-Running Process is sometimes called a Saga

E.1. Handling more than one event

A filter can handle more than one event, for example if a Filter handle two events from two processes, one can be a short running and the other a long running . Because the execution is in parallel now the main issue is to tell to the filter or to inform him that the long running one has finished his work

long running processes

Extending the previous example, we could create parallel pipelines by adding just one new Filter, TotalPhoneNumbersCounter, as an additional subscriber to AllPhoneNumbersListed. It receives the Event AllPhoneNumbersListed virtually in parallel with the PhoneNumberFinder. The new Filter has a very simple goal, counting all existing contacts. This time, however, PhoneNumberExecutive both starts the Long-Running Process and tracks it through completion.

And the point for the filter is :

Now it is the responsibility of PhoneNumberExecutive to subscribe to two Events, both MatchedPhoneNumbersCounted and AllPhoneNumbersCounted. The parallel processing is not considered completed until both of these Domain Events are received.

F. How to know the end of the long running process ?

There is a problem with this Long-Running Process, however. The
PhoneNumberExecutive currently has no way of knowing that it has received the two completion Domain Events associated with the specific, corresponding parallel processes.

We can combine two ways to give a solution to the problem.

F.1. Unique ID

The first step in the solution to this troublesome situation is to assign a unique Process identity that is carried by each of the associated Domain Events. This could be the same identity assigned to the originating Domain Event that causes the Long-Running Process to begin (for example, AllPhoneNumbersListed). We could use a universally unique identifier (UUID) allocated specifically to the Process.

F.2. Tracker

Create a Tracker that tracks each of the associated events of course with the verification of the ID of the associated events

In an actual domain each instance of a Process executive creates a new Aggregate-like state object for tracking its eventual completion. The state object is created when the Process begins, associating the same unique identity that each related Domain Event must carry. It may also be useful for it to hold a timestamp of when the Process began (the reasons are discussed later in the chapter). As each pipeline in the parallel processing completes, the executive receives a corresponding completion Event. The executive retrieves the state tracking
instance by matching the unique Process identity carried by the received Event and sets a property that represents the step just completed
.

tracker

Not to be overlooked is that the Long-Running Process executive can publish one, two, or more Events to initiate the parallel processing. There may also be not only two, but three or more subscribers to any initiating Event or Events. In other words, a Long-Running Process may lead to many separate business process activities executing simultaneously.

G. Event Sourcing

G.1. The Problem

With an increased desire for even more change tracking, the business demands more metadata. It begins to care also about the individual operations that were executed over time. Maybe it even wants to understand how long certain operations took to execute. Those desires lead to the need to maintain an audit log or journal of the finer-grained use case metrics. But an audit log or journal has its limitations. It can convey some information about what has happened in the system, perhaps even allowing for some debugging. But it doesn’t allow us to examine the state of individual domain objects before and after specific kinds of changes. What if we could stretch more out of change tracking?

G.2. Why we need it ?

As developers we have all experienced finer-grained change tracking in one form or another. The most common example is with the use of a source code repository, such as CVS, Subversion, Git, or Mercurial. What all of these variations of source revision management systems have in common is that they all know how to track changes that occur on a source file. The change tracking provided by this genre of tool enables us to go all the way back in time, to view a source code artifact from its very first revision, and then to proceed revision by revision, all the way to the very latest. When committing all source files to revision control, it can track changes of the whole development life cycle.

G.3 Solution

Now, if we think about applying this concept to a single Entity, then to an Aggregate, then to every Aggregate in the model, we can understand the power of change tracking objects and the value it can produce in our systems. With that in mind, we want to develop a means to know what occurred in the model to cause the creation of any given Aggregate instance, and also what has happened to that given Aggregate instance throughout time, operation by operation. Given the history of everything that’s happened, we could even support temporal models. This level of change tracking is at the heart of a pattern named Event Sourcing.

event sourcing

Conclusion : For me that architecture is for a very low coupling between bounded contexts and to make everyone independent, because the only thing that link a Bounded context to another is the Domain Event

See you next time 😁 if you want to add some insights feel free to comment !

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.