I have an event driven architecture where A is waiting for a change from B and B is waiting for a change from C and C is waiting for a change from A, forming a cycle.
Now, if B changes, then A fires an event to C, which fires to B, which fires to A, which fires to C...ad infinitum.
I can change my program right now to not contain this cycle, but I am concerned I may put myself into a corner at a later time where I cannot. How does one keep such things from happening when designing event based systems?
Event-Driven Architecture definition: Event-driven architecture is a way of building enterprise IT systems that lets information flow between applications, microservices and connected devices in a real-time manner as events occur throughout your business, instead of periodically polling for updates.
Event-driven architectures are reliable, performant, easy to maintain and extensible. But to unlock these benefits an application needs to be designed with events in mind.
Benefits of event-driven architecture. Event-driven architecture can help solve the problems of the close coordination of microservices, error handling and retries, and coordination between development teams.
An Event-Driven Architecture for data and applications is a modern design approach centered around data that describes “events” (i.e., something that just happened). Examples of events include the taking of a measurement, the pressing of a button, or the swiping of a credit card.
Everybody here seems to say that cyclic dependencies are bad. This correct in a sense and I try to avoid static cyclic dependencies at almost all costs. You can do so with inversion of control as sketched in this blog: http://blog.schauderhaft.de/2011/07/17/breaking-dependency-cylces/
But what you describe is not necessary a static cyclic dependency, but one at runtime. I'm not completely sure, but I think it is more or less impossible to avoid cyclic dependencies at runtime. But of course this should not result in endless loops. To fix those I see two and a half options
First the hack
Make sure each event triggered by another event has a reference to the original event (or essential information about it like an id). When ever you process an event make sure it doesn't originate from your self.
Pro: easy to implement; prevents recursion absolutely
The other half of the hack
If you are running synchronous you can set a flag firingEvent
before and resetting it after. Ignore events comming in while firingEvent
is set.
Pro: even easier to implement; prevents recursion absolutely when running in a single thread
Semantic rich solution
I'm convinced that the event that A fires on some outside trigger and the event that A fires because C fires are really two different events, or all three events are really just one which might come from a yet to be identified source D. Or something like that. There is no way telling without information abut what A, B and C are and what events they are firing. If you find the proper events the cycle will disappear.
Pro: The design will be cleaner and contain more information.
Map out your dependencies. There should be no cycles. Cyclical dependencies are a good excuse to reorganize your code.
They can also cause deadlocks, in case you needed another reason to try to avoid them.
How does one keep such things from happening when designing event based systems?
Raise event only when object state really changes.
Prohibit object state changing while event is raised.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With