I was trying to model a fairly simple real world model inside a distributed system and got stuck thinking about timing and order and would appreciate some external view on it.
Assuming I have this simple model
- The actor produces a fixed "income" at the end of each month
- The account produces a "balance" at the start of each month
These objects are connected via an event broker that adds latency, caching and all the other complexity of distributed systems.
I've tried to design this solution with a message broker. I also added an actor that produces "time" events. The time-actor creates two events: "end of month" and "start of month" to inform all listeners that time has passed. See it as a logical clock.
However, while producing "income" events and "balance" events appear straight forward on paper, I run into order of execution issues, which turns out, is essentially a race condition between the individual topics (channels) of the system:
In this image you see that the time producer produces the "end of month" event that causes the actor to produce an "income_produced (1000)" event.
Very shortly after, the next event "start of month" event is produced. The account object has not yet caught up with the income_produced event. Because the time events were very close to each other.
Now there is a race condition for account, if it receives the income_produced event before the "start of month" event, it will report the correct account balance. If the order is reversed, it will report the wrong balance.
This is intentionally a "bank account" example and I fail to see a good solution to be strongly time ordered.
There is no way for this system to ensure "enough" processing time has passed between "end of month" and "start of month" to let all objects "catch up" with the state.
How is this usually solved?
I am aware, that one workaround would be to use not three but only one topic / channel in a system were at least the order of operations inside one topic would be correct enough, when the order of writes is correct. (Kafka would for instance also require it to be a single partition, AFAIK).
But if I would design a more complicated system, then there would be many more topics / channels, on which the objects operate. Forcing them all into one single topic / channel would introduce a lot of complexity, since all objects would need to read and potentially discard a lot of messages, which are not relevant for them. Also the entire system would essentially become one single sequential system, which feels odd.
How would somebody with more experience approach this?
Edit: Minor clarification: This is not an approach to fully model how banking or accounting (in the US or anywhere) works. It is just a prototype I am thinking about to explore the problem-space where I was checking whether eventual consistency could work or where I am making wrong assumptions about the concept.

