Closed martinklepsch closed 4 years ago
It seems that this commit https://github.com/clj-commons/citrus/commit/61210a388f25bf592ae7b9d7d44c2cc5ff12ac72 makes a change in the same direction (passing the entire state to every handler). Appears to be unreleased so far and also breaking in terms of API compatibility.
@martinklepsch I like the idea with the default handler. Would you want to put an exploratory PR? Perhaps you would want to revert 61210a3 before making changes.
I've started to work on this just now. One question: In the queue-backed dispatch!
implementation, why is an anonymous function added to the queue instead of the raw data?
@martinklepsch Perhaps just implementation detail. Feel free to change it.
EDIT 2020-03-09: This thread discusses the introduction of a
:default-handler
option – please share your feedback/experiences if you've used it.Hi all,
We’re currently looking into adapting Citrus so that all controllers methods can access the state of other controllers. In our particular use case we found that we often end up passing central information around in events such as the current users ID. This adds complexity to components because components then need to get this data out of the
:users
controller first.We're interested in either something that would allow us to have "shared state" between controllers or a way that would allow us to access individual controllers' state from the methods of a different controller.
There's a few different options I've been mulling over, would be curious what others thing about those.
1. Pass entire reconciler state as 4th argument to multimethods
Handlers would take the fourth argument
2. Default handler option
This is an option I'm very curious about because I think it makes Citrus very versatile and allows existing codebases to gradually migrate out of the predefined controller design while maintaining backwards compatibility. This is not to say that the controller structure is bad. But codebases grow and knowing that it's possible to break out when needed can be great for peace of mind. I know we are at a stage where we have some long-term concerns around building on top of Citrus but a rewrite is just not something that we'll prioritize over product work.
The basic idea is that whenever
dispatch!
is called with a controller name that doesn't exist in the reconciler it will call a default handler with the following args:This would allow user-land code to basically do anything. For instance we could remove some of our controllers from the
:controllers
map and implement adefault-handler
like this:This implements the suggestion in 1. but possibilities are endless. We could implement an interceptor chain on top of this for instance, which I believe isn't possible with the current controller/multimethod based approach.
I'm not sure what or if this would break with regards to other Citrus features but I think it would be amazing if Citrus had an escape hatch like this that would allow implementing more complex handlers than what's possible with multimethods.
Other solutions to the general problem of accessing central data
Use
broadcast!
morebroadcast!
to make central pieces of information available to multiple controllersCustom effect to mirror data to multiple controllers
:shared-state
effect that writes data to every controller in the reconciler