Allow invoking interpreted machines #1306
Replies: 3 comments 3 replies
-
So why this proposal?I stumbled upon this while trying to get a web component to spawn a complicated dialog (a different component) to retrieve the user's input. Every web component has its own state, so owns and operates its own interpreted machine. Since the appearance of the dialog is however fully dependent on the current state of its parent-element('s state), it felt right to use If the user leaves the parent state that invoked the dialog, it should disappear, which is an "automatic" behavior with invoked Machines, that could be (somehow) extended to Services. All that is clearly not working at the moment (V4), requiring the use of some hacky work-arounds instead, hence this proposal. |
Beta Was this translation helpful? Give feedback.
-
Thank you for the proposal write-up. I feel like we should limit this proposal to only invoked and started services (interpreted machines). The problem with "the machine was interpreted but has not been started" is - what if two separate services invoke the same machine at the same time? Do they both start them? Do they both have ownership? How does this affect Already started services should have the parent that they were created with (actors can't "change" their parent in the same way that we can't change our biological parents). Also, we shouldn't But yes, the minimal viable behavior should be that some service should be able to communicate with an existing service by "invoking" it. That existing service can communicate back by using |
Beta Was this translation helpful? Give feedback.
-
In more traditional actor systems "everything is an actor". This has a consequence of actors always being invoked by other actors - there is just no way to spawn an actor "out of thin air". I'm not well-versed in web components API (I know the concept though) so I would like to talk about a more concrete situation using React app as a base. It's also component-based so I would really expect both systems to have very similar traits and possibilities. I think we can distinguish 2 main situations possible:
From what you are saying I assume we are talking about the first situation here and I think we can go about implementing this in two ways:
There doesn't seem to be much of a problem with the first approach as the whole logic just lives in a single place~ and I don't see any potential concerns/doubts one could have about it. I understand though why you would like to use the second approach - it definitely has its merits thanks to better colocation of logic & rendering concerns. Knowing that we are looking only at parent-child relationships right now - it should be easy to just export a machine and a component separately from the child so the parent could both invoke that machine and render that component in a very natural way. While doing this you would have to pass the created children service (accessible in Does this solve your concerns? Have you envisioned the glue code between those 2 differently? What kind of problems do you see with the proposed approach? |
Beta Was this translation helpful? Give feedback.
-
Proposal
The
invoke
-property currently allows for the following values:I would like to add another option:
State of a Service
There are two possible states of the invoked service:
e.g.
const serviceToInvoke = interpret(childMachine)
e.g.
const serviceToInvoke = interpret(childMachine).start()
If the service was already started, fine. But if the service has not yet been started, then upon invoking it, it should immediately be started.
The
data
-propertyCurrently, when a Machine is provided to
invoke
, an optional propertydata
is available to allow the context of the invoked machine to be primed with data from the parent's extended state. See the example below:The question is how to deal with this property when a Service is being provided instead? See the following three options:
assign
ing it to interpreted machine's context)I would think option 3 would be optimal as it gives the most flexibility and has not real disadvantages (as far as I can see). It could potentially be made even more powerful by also providing the context of the (invoked) interpreted machine as an additional argument to this function. Then one could really finetune how the interpreted machine's extended state should look like after having being invoked.
Upon leaving the parent's state
With machines, leaving the state in which the machine was invoked, would stop the (under the hood) interpreted machine's instance. The question is wether this should also occur when a service was directly invoked. A case could be made for when the service had not been started yet before it was being invoked, to follow this behavior. When the service was already started however, this might not always be preferred.
To keep things simple, I would have no objection to the service being destroyed upon leaving the associated parent's state. However, my preferred solution would be to instead implement some mechanism by which the invoked service would be notified and allowed to act on itself.
I have no exact mechanism for this in mind at this moment however.
Beta Was this translation helpful? Give feedback.
All reactions