What is the formal name for this specific problem scenario in an event-driven architecture, and what are the common approaches to handle it?: After an action or event is dispatched, several subscribers will execute in order. But after the first subscriber is executed, it triggers a new action which also has several subscribers, and so on. At some point, some subscriber is going to require data from other models that depend on the first action, but haven't been updated yet. See the diagram:
as Dunk suggested, the way I solved this was by redesigning and by using a 3rd entity to handle the initial event and then for ensuring sequencing is in the proper order.
Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators.
So the result is something like this:
I'm not going to go deep into rx, but basically we treat each event emitter as a stream of data. This stream of data is usually handled as a static array. We can do whatever we want with the streams, and if we build a chain of streams, we will always have an up to date stream at the end of the chain.
So the pros of this approach are:
- You will learn a new programming paradigm (if you don't know already)
- You don't have to reinvent the wheel making a complex event management system.
- Once you master it, it will become very easy to handle large streams of events.
- You have to refactor. It can be done partially, however you will need a good understanding to do it.
- Really, REALLY steep learning curve (at least for me it was). I never worked with reactive or functional programming, so for the first time it took me and my team a while to switch our brains into functional thinking.
- A little bit tricky to debug and unit test, but not impossible.
A possible approach to handle this is to pass a unique ID or token from the initial event source through the chain, so the "join node" can compare this ID for the incoming events and associate the correct states by matching IDs. In real world scenarios, things can become more complex (for example, timeout scenarios, buffering of events, join node might react on partial input, whatever you can imagine).