Closed Kazark closed 9 years ago
One thing I haven't done yet that needs to be done---and this is part of the reason for not using a command message---is handling NoResponseToRequest<>
. I think this is a powerful feature that could allow us to decouple the microservices to an amazing level. (For example, if you have a service that is providing you with an option but does not respond, you can fall back on a default.) That might be considered overcomplications, but I rather think it might be defensive programming. At the very least, if something that was expected to happen did not happen, we can report it to the user/developer.
Is this good to go?
Yep, it is awaiting only your stamp of approval. :grinning:
You may have to resolve a merge conflict though after you merge one of these. Or I can resolve it.
Feel free! Merge it up :+1:
So after a little more time to look at this, I've figured out that it's basically crap. There are at least four major problems with it.
A
and service B
both make a request to service C
, they will both be notified of a response, with no way to tell whether or not they asked for that response. If the resultant action is not idempotent, this will trigger undesired behavior.I need to design a solution that will take care of these. Honestly, I think I may just need to inject a request
function. That will:
Some response
, or None
.Disadvantages of this suggestion:
:crying_cat_face:
Sad panda :panda_face:
There are three ways for services to interact given the current architecture, in order of preference. The items lower on the list sometimes have the correct semantics for the problem, in which case they are to be employed; but the items higher on the list are to be the preferred mode of thinking.
This updates #3 so that it also is using messages.
My motivation for doing that right now is that I think anything where the screen is refreshed as a result of an event or command that does not alter the state of the core editor is best handled with request/response semantics. This is because though there is an event that triggers this, it feels like domain leakage to let the core editor have knowledge that that view event. And thought I could use a command to request the necessary information---wait. I just said request. So doesn't that mean that the semantics are request/response?
The thing is, the view will fail to refresh unless it gets a response from the core editor. This means that it is dependent for doing its job on the core editor, and as such, it probably needs stronger semantics than commands. Commands are really supposed to be used for "do" instructions, not "get" instructions.
So given that I am working on some things that need request/response semantics, I chose to make this change because I am not comfortable with the inject functions strategy. It feels too coupled, is not flexible, and creates some complicated construction logic that is dependent on order of construction. Overall, too, as I'm evolving the code to have a more functional appeal, I am becoming increasingly suspicious of dependency injection.
The caveat is that this may be a premature abstraction. I've been working a lot in the infrastructure at work and have been having to do some pretty heavy magic to accomplish it. While appropriate for the particular project I am working on at work right now, this is probably inclining me back toward the magic code that I am naturally inclined toward but have rightly been taught to regard with suspicion.
To go further into the details of the advantages of this approach, it does not force you to unify the request handling services into a single function call. For example, if we end up with different services to handle different types of buffers, then services should be able to filter whether they service a request dependent on what the buffer ID is. Or closer to our current use case, if we are executing Python code in command mode instead of VoidScript (though that is also speculative, it is a goal) entirely different services can execute different types of code, without having to have a service which coordinates or manages them.
Also, it unifies the architectural communication options, and more strongly accents the fact that is a messaging architecture, and clarifies that services really shouldn't be referencing each other, and for the most part, shouldn't even reference each other's data types. On the flip side, the convenience of it may encourage a more orchestrated mindset, and I do not want this. Favor events.
Another thing I'm stepping toward here is the possibility that the ViewModel would not have a reference to the Core assembly at all, perhaps only to a message contract assembly. That's just one future possibility, however.
This should not be merged without discussion.