Sunday, September 1, 2019

Domain Events Martin Fowler

Domain Event

Captures the memory of something interesting which affects the domain
Captures interesting events in the domain that cause multiple reactions and those multiple reactions are unknown or may change over the period of time.

Many things happen in the Domain, Many Transactins and Domain Model State Changes occur in the Domain Model/DB. 
But we have to analyze, this Change to the DM state is significant, this may cause other actions to provoke. 

Silent Domain Model Changes
Reactive Domain Model Changes.

There are two extremes to which Domain Events can be used.

Without Event Sourcing
======================
We just need Events and Event Processing Queues. We log Events just to process them. We do not store the Events themselves.

With Event Sourcing
==========================
We use Domain Events, Event Logs, Event Processing all is there.
But additionally, we save those events as well.

Why We Need Event Sourcing.
================================
Normally we just apply the change to the Database. 
We just update the database with new state. 
We do not save the Change Set. 
Drawback is we cannot revert back to any initial position.
We cannot analyze the Recent Change Set happened inside the system.
We cannot do the AI, Predictions, Data Analysis, Trends.
We must save both Changes and the Final State of the DB.

Sync. Methods are one way to update the State of Domain Model in the DB. Fire and Wait, Complex Error Recovery, Locking, Slow, No Change Log is stored. Response Code is fixed, To change Response Code we need to Change the Application.
If error recover fails, DB can go in inconsistent state.

Async. Methods are another way to do so. Fire and Forget, Simple Error Recovery, Response Code will be done in Handler, No Locking, Fast, No Change Log is stored. Response Code is fixed, To change Response Code we need to Change the Application.
If error recover fails, DB can go in inconsistent state.

Simple Domain Events are extensions to the Async. Methods in a very neat clean way. Fire and Forget, Simple Error Recovery, Response Code will be done in Handler, No Locking, Fast, No Change Log is stored. Response Code is dynamic and can be changed at run time or deployment time. Response code can be configured at deployment time. No need to change the application code.If error recover fails, DB can go in inconsistent state.

Domain Events with Event Sourcing are extensions to the Simple Domain Events in a very neat clean way. Fire and Forget, Simple Error Recovery, Response Code will be done in Handler, No Locking, Fast, Change Log is stored. Response Code is dynamic and can be changed at run time or deployment time. Response code can be configured at deployment time. No need to change the application code.If error recover fails, 
Less chances that DB can go in inconsistent state because we have Event Logs, Event Queue, Event processor.

==================================



Subject is Entity or Aggregate Root whose state is going to be changed in response of Event being raised.

It could be the Entity or Aggregate Root whose State Change is to be modeled as Event

One Event is related to one Subject ????
One Subject can have many Events True
One Event has One Event Type ?????
One Event Type is related to many Events????

Event is the Use Case or Transaction or Requirement level thing or Verb that happens in the system. It corresponds to the Method in programming. It is a big concept. One Method Call could result in multiple method calls and multiple DB updates. In the same way One Event can cause multiple Event Types and multiple DB updates or work.

Event Response code could contain any thing.
Direct DB update
Send Email
Send Notification
Log the Event
Call another Web API Service that cause update DB, Email, Notification

In case of Web Application these events are done in the momentous object graphs.

Event Type ?????? 

I go to Babur's for a meal on Tuesday, and pay by credit card. 
Make payment by the Credit Card is a use case that effects the state of Domain Model in DB and we might be interested to propagate that as an event and we want to do multiple things in the response. 
An important transaction in the business and many stakeholders are affected by this. There could be events in the system those are less importannt and have very small impact on the system. 

High Impact Events/Use Cases are modeled as Domain Event

This might be modeled as an event, UC or Requiremnt
event type is 'make purchase' or Class that Model the Event/Data
whose subject is my credit card, Entity affected by Event in DB
and whose occurred date is Tuesday. 

If Babur's uses an old manual system and doesn't transmit the transaction until Friday, the noticed date would be Friday.

Things happen. Not all of them are interesting, 
UC happen some are low impact and other are high impact and important

some may be worth recording but don't provoke a reaction. 
Some events are need to be stored in event sotre but no reaction code is there.

Some events are needed ot be recorded in DB but does not cause great Reaction Code, Reaction Scope is limited. 

The most interesting ones cause a reaction. Many systems need to react to interesting events. 
High Impact Use Cases are done as Domain Event. These Events are recorded and as well as there is Reaction Code against the Events.

Often you need to know why a system reacts in the way it did.
Why we need to model such UC as the Events

Rather than simple Methods Calls or Async Method Calls, these UC are modeled as Events. This approach has many advantages.
Events those cause changes can be stored as well. We and go back to any previous state of the DB, and analyze when this bad thing has happened. 

It is like the Code First Migrations of EF. All Change Set is saved. All Schema Changes are kept as migrations. 
We have our final state of the DB SChema as well. We can revert Db Schema to any previous state. 

Same is the case with the Version Control Software. Final State of Code bases. Changes to the Code bases. Revert Code base to previous state. 

By funneling inputs to a system into streams of Domain Event you can keep a record of all the inputs to a system. 

keep the record of all Events/Method Calls to the System
kepp record of all Method Calls those case update DB and also save the parameters.
Method Call == Event 
Method Parameters == Event Type/ Event Data Container

This helps you organize your processing logic, and also allows you to keep an audit log of the inputs to the system.

How it Works

The essence of a Domain Event is that you use it to capture IMPORTANT & INTERESTING things / Use Cases/ Events/ that can trigger a change to the state of the application you are developing. THERE ARE MANY STATED HOLDERS THOSE ARE INTERESTED IN THAT IMPORTANT STATE CHANGE. 
These event objects are then processed to cause changes to the system, and stored to provide an Audit Log.
EVENT LOG == EVENT STORE
EVENTS ARE ALSO STORED FOR AUDIT LOG AND TRAILING
EVENT PROCESSOR == COMPONENT THAT ANALYSE AND PROCESS THSE EVENTS AND CAUSE THE STATE CHANGE IN THE DB
YOU CAN IMAGINE THAT ARE SAVE THE METHOD CALLS WITH PARAMETERS IN A QUEUE, THEN A EVENT PROCESS PROCESSES THESE METHOD CALLS AND DO THAT INTEDED THINGS.

Figure 1: Events funnel inputs into a single source.
Figure 1 helps illustrate the point. 
Here we have a system with inputs from a 
  • user interface, 
  • messaging system, and 
  • some direct manipulation of database tables. 

In order to resolve these to Domain Event we have components that interact with each of these input streams and convert the inputs into a stream of Domain Event which are stored in a EVENT OR persistent log. 
DATA INPUT STREAMS ===> PROCESSING COMP ==> DOM. EVENT STREAMS  ==> EVENT LOG/QUEUE ==> EVENT PROCESSOR
DATA INPUT STREAMS PROCESSOR THAT CONVERTS DATA INTO EVENTS
EVENT PROCESSOR THAT PROCESS THE DOMAIN EVENTS AND UPDATE THE STATE OF DB OR DO THE OTHER REACTIVE THINGS.
An event processor then reads the events from the log and processes them triggering our application to do whatever it's supposed to do.

TWO PROCESSING LAYERS. 
IST PROCESSING LAYER ==> CREATE AND LOG EVENTS
2ND PROCESSING LAYER ==> PROCESS THE EVENT

AS EVENTS ARE ONLY KNOWN THE ASPPLICATION, THERE FOR SENDING APPLICATION CANNOT SEND EVENTS DIRECTLY TO THE EVENT LOG. WE NEED MIDDLE COMPONENT. 

In this stream the first input layer of the system takes no action to the stimulus/INPUT STREAM other than to create and log an DOMAIN event. 

The second layer can then be ignorant of the actual input source, it just reacts to the event and processes it. PROCESS WHAT EVER IS THERE IN THE EVENT QUEUE. 

For this example I've shown just the one event log. 
In practice it often makes sense to separate the logs if the events have different response requirements. 
DIFFERNET TYPES OF EVENTS HAVE DIFF TYPES OR RESPONSE. IF THE RESPONSE IS DIFFERNET, WE NEED TO LOG IT ON THE DIFFERNET EVENT LOG/EVENT PROCESSOR.
ONE TYPE OF EVENT LOG IS RELATED TO ONE TYPE OF EVENT PROCESSOR AND CAN GENERATE RESPONSE TO ONE TYPE. 

ONE EVENT LOG FOR DB OPERATIONS
ONE EVENT LOG FOR EMAILS
ONE EVENT LOG FOR NOTIFICATIONS
ONE EVENT LOG FOR CALLING MESSAGING SYSTEMS

THEY MAY ALSO BE CATEGORIZED BY WHAT TYPE OF SOURCE IS SENDING THE INPUT STREAM.

UI GENERATED INPUT STREAM TO ONE EVENT LOG
MESSAGING SYSTEM INPUT TO ANOTHER EVENT LOG
DIRECT DB SERVER INPUT TO ANOTHER EVENT LOG

A user interface will typically want a much faster response time than many remote messaging systems, so it makes sense to 
put user interface traffic into a different log and use a separate processor for them. OR WE DO NOT USE LOG AT ALL.

SEPARATE EVENT LOG/PROCESS FOR INPUT STREAMS COMING FORM UI
SEPARATE EVENT LOG/PROCESS FOR INPUT STREAMS COMING FORM MESSAGING SYSTEM
SEPARATE EVENT LOG/PROCESS FOR INPUT STREAMS COMING FORM SEPEARTE DB SERVER

The diagram implies an asynchronous pipes and filters style of interaction, but this isn't an essential part of the approach. 
EVENT LOG CAN BE OPTIONAL IN CASE OF UI INTERACTION

IT COULD BE THE  asynchronous pipes and filters style of interaction,

OR IT COULD BE THE SYNC. COMMUNICATIONS

Indeed a common approach, particularly with user interface stimuli, is to have the UI handler invoke the event processor directly in a synchronous interaction WITHOUT HAVING EVENT LOG IN IT. SO IN CASE OF UI, AS WE NEED QUICK RESPONSE, THRE IS NOT EVENT LOG PART. EVENT GOES DIRECTLY TO THE EVENT PROCESSOR AND WE GET THE RESULT

Each Domain Event captures information from the external stimulus. Since this is logged and we want to use the log as an audit trail, it's important that this source data is immutable. That is once you've created the event object this source data cannot be changed.

DATA THAT IS SENT FORM EXT SOURCE CAN BE CHANGED ONCE IT IS STORED IN THE EVENT LOG AND EVENT OBJECT IS CREATED. 

However there is also another kind of data on the event that 
records what a system has done with SOURCE DATA - 
I call this the processing data
I characterize the data on a Domain Event as immutable source data that captures what the event is about 
and mutable processing data that records 
what the system does in response to it. 

Source data on a credit card charge would include how much the charge was for, who the vendor was, etc. THIS INFO SHOULD NOT BE CHANGED. HOW MUCH CHARGE, WHO THE VENDOR WAS.

Processing data might include which statement it appeared on. ?????????? STATEMENT MAY INCLUDE THE INFORMATION THAT HOW MUCH CHARGE, WHO THE VENDOR WAS.

If your PROGRAMMING platform has particular support for immutable objects it may be worth splitting the event into two objects to take advantage of this.
Although the source data can never change, it may be that the system needs to handle a change - typically because the original event was incorrect. ORIGINAL EVENT WAS ERRONEOUS.

You can handle this by receiving this change as a separate Retroactive Event. The processor then handles the retroactive event to correct the DATABASE consequences of the earlier erroneous event. REVERSE THE EFFECTS OF THE ERRORNEOUSE EVENT. 
Often this processing can be done at a very generic level.????????
A third, but only occasional, category of event data is 
cached data from derivations from other data on the event stream. ??????????

In these cases the event processor summarizes information from past events while processing the current event and 
adds that summarized data to the current event to speed up future processing. 

Like any cache, it's important to signal the fact that this data is free to be removed and recalculated should any adjustments occur.?????????
Different events occur for different reasons, so it's common to use different types of events. The event processor will then use the event type as part of its dispatch mechanism. The type of event can be represented by using sub types of events, or a 
separate event type object, or a mixture of both.
It's quite common that different types of event carry different data, so using sub types of event for the event types fits in well with that. The problem with sub types is that this leads to a proliferation of types, that is particularly frustrating if much of the data is the same. A hybrid approach uses sub types to handle different data and event type objects to signal dispatching.
Events are about something happening at a point in time, so it's natural for events to contain time information. 

When doing this it's important to consider two Time Point that could be stored with the event: 
the time the event occurred in the world and 
the time the event was noticed . 

These Time Points correspond to the notions of actual and record time.

Actual Time of Event
Time when the event was noticed by the system
Of course you don't always need both Time Points, but you should always consider whether you need both. 

The danger is picking one Time Point, and not being clear which Time Point you picked, either at the time or later. 

So I also suggest you name the Time Point clearly to indicate which one it is.
It's possible you may need multiple record Time Points to record when the event was noticed by various different systems.

When to Use It


Capturing system stimuli through Domain Event is a significant decision. 

It imposes a distinct architectural style on an application and a programming model that will often seem awkward - at least initially. 

At this point it's not clear whether this approach actually is any more effort once you've got used to it.
Despite its unusual nature, I see some significant benefits for using this approach.
The Audit Log of events provides a full record that is valuable both for audit and debugging purposes. 

If the system gets into a strange state you have a full log of the inputs that got it there. 

By storing the events that were actually processed 
you decrease the chances of 
neglecting to write important information to the Audit Log.
Clear event streams make it easier for other system to replace some or all of an application in the future by adding a Message Router to divert events to a new system. ????????????????

Although it isn't fashionable to design a system in a way that facilitates its eventual demise, the sheer frequency of system replacement projects should mean we ought to pay more attention to it.
Domain Event is particularly important as a necessary pattern for Event Sourcing, which organizes a system so that 
all updates are made through Domain Event.

No comments:

Post a Comment