Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle incomming integration events? #14

Open
alibabashack opened this issue May 23, 2024 · 2 comments
Open

How to handle incomming integration events? #14

alibabashack opened this issue May 23, 2024 · 2 comments

Comments

@alibabashack
Copy link

Thank you very much @eugene-khyst ! Especially the paragraph about Domain events vs Integration events was an eye-opener.

I am currently wondering how replaying of events works and how the system state can be reliably recreated (conceptually). A reason to do that might be an added or modified projection (e.g. to add another column in a table providing extra information which can be extrapolated from existing events).

This seems to be strait forward when only internal domain events contribute to the aggregate's state. We simply drop the table(s) belonging to the projection, then pipe all historic events through the new/changed event handler of the projection and finally continue to feed new events synchronously.

But, can't we also have aggregates that perform state changes due to incoming integration events? (I am unsure if this is conceptually correct.)

How would we deal with incoming integration events in this case? In order to be able to replay events later, it seems to me, that the incoming events need to be enqueued into the event store along with the internal domain events, because only then we are able to preserve their exact order of processing relative to the internal events.

So in this case we had some process receiving incoming integration events. First, it sticks them into the event store (while dropping repeatedly delivered events). Then it hands them over to synchronous event processing (but not asynchronous forwarding). Finally, it acknowledges the reception to the event broker.

Does this sound valid or is there a better pattern? I am thankful for every comment.

@eugene-khyst
Copy link
Owner

Hi @alibabashack
Before trying to answer your question, I want to make sure I fully understand it. Could you please provide an abstract example of the domain you describing? I can extend the repo to have a section dedicated to this example.

@alibabashack
Copy link
Author

alibabashack commented May 23, 2024

Okay, it might feel a bit staged, but let's amend your example with an additional service called Driver Work Time Tracking. Among other things, this service is also used by drivers to call in sick. The service has a command callInSickForToday(driverId).

And there is a new business rule:

Given a driver has accepted an order and given the order is not completed yet, when this driver is reported absent, then the order is canceled.

Let's assume we want to implement this using the event choreography approach. Hence, there is no direct command from the Driver Work Time Tracking, but instead DriverAbsent(driverId) integration events are emitted towards the Order service using some kind of message broker.

My questions are:

  1. What happens in the Order service when a DriverAbsent event is received in order to potentially cancel orders (and how do we receive it).
  2. How is event replay working at a later stage and which events will be replayed to restore the state?

Meanwhile, I understood that an aggregate is not allowed to change state by accepting events directly (neither internal domain events, nor integration events). An aggregate only acts upon commands. Events being emitted is the result of a command, only.
Hence, the incoming integration event DriverAbsent is not stored in the event store. It is rather transformed by Something* into a command towards the Order aggregate. In case this command execution results in a state change, only then an OrderCanceledEvent will be emitted. And this is sufficient to restore the state in case of a replay. Correct?

  • What is this Something called? If it is a complex thing it seems to be called Saga, but what do we call this simple thing that can't fail, here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants