Event driven architecture…infinite loop

心不动则不痛 提交于 2019-12-10 12:44:15

问题


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?


回答1:


Cyclic dependencies are really bad. I had to write down your post in terms of A, B, and C before it even made sense to me. I think you should get rid of it. If you're putting yourself in a corner, it's probably a whole lot better than the problems you can run into with cyclic dependencies.

You can definitely avoid this, too. A, B, and C are really tightly coupled. I think you need to rethink their responsibilities. Perhaps there's a common D element that'll take a lot of your design-stress away.

Something else that comes to mind is architectural Layering. If you can layer A over B, and require communication by anyone speaking to B to go through A and down the layers, you might give yourself an easier time. Again, I don't know much about your problem, so these are just broad suggestions.

One final option, and my least favorite, is to pass a message between each of the three components. As each is visited, require that each component add to the message that it has seen the message. Then the next component to get the message has information about who's seen it. Kind of like a sign up sheet. But again, least favorite. Try something else first.

Good luck!




回答2:


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.




回答3:


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.




回答4:


How does one keep such things from happening when designing event based systems?

  1. Raise event only when object state really changes.

  2. Prohibit object state changing while event is raised.




回答5:


I think this is a good question. Unfortunately I don't have an full answer myself, but this post has a couple good points:

how to avoid infinite loop in observer pattern?

I don't think the answer is to avoid cyclic dependencies, as others have suggested. (Well, it depends on your definition of "cyclic dependency".) A language like Java will use interfaces to minimize cyclic dependencies of types at compile time, which is often a good idea. For example, a view class in the MVC pattern does not "depend" on your application, it only knows about interfaces with names like ValueChangedListener, ClickListener, etc. But this does not eliminate cyclic connections among objects at run time, which is what can lead to event loops.

As mentioned in the other linked post, some loops are stopped in UI toolkits because the view won't fire a 'changed' event if the controller or model "sets" the view's value to something equal to it's current value. But in other cases, like when you create a custom view of a more complex piece of data, it can be infeasible to compute equality of the current and new data.



来源:https://stackoverflow.com/questions/3688117/event-driven-architecture-infinite-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!