I think, hierarchical decomposition is a nice idea to hide complexity, in particular in graphical representations, but also for the sake of being able to have several alternative ways to implement the “internals” of a (top-level) object. I think, it is worthwhile to spell out the nice properties of this decomposition on the underlying message sequence charts in terms of refinement as covered in §5 of this thesis, titled
Distributed System Design with Message Sequence Charts.
Roughly, each incoming message is replaced by a whole diagram of messages, on the level of the graphical representation.
Each step [1] can be represented as an “activation box” in a diagram of messages, with incoming and outgoing arrows, looking something like the following picture:
Now, we may open up the activation box, to find that there are additional messages sent “inside” object 1, and that the messages m2 and m3 actually have different “actual” senders, which send on behalf of the surrounding (top-level) object.
If we keep expanding boxes, we eventually reach a most refined level. On the level of message sequence charts, we have additional scopes, which describe which messages are to be considered direct causes of each message (relative to an object).
I hope that this is a proper interpretation of the decomposition that you have described.
The interesting point now concerns the transactional structure of each (top-level) activation box. This is usual the hard part if we think of the “usual” actor model, because one would have to add a final join/sync of sub-objects so that we are sure that either all or none of the messages will be send. For the above example, a third sub-object object 1.3 would have to sync the objects 1.2 and 1.1 and send the messages m2 and m3[2].
However, if all (top-level) messages are (non-ephemeral) resources, then we simply simply wrap the (top-level) step into a transaction with all the internal messaging represented by (ephemeral) resources. Thus, I think, the decomposition principle is good to go essentially as described. The interesting questions arise of course when one does not have the “enclosing” controller that makes sure that we can fabricate a single transaction that bundles together all the steps of the sub-objects into a single step of a top-level object (cc @isheff).[3] But that would bring us into the deep waters of distributed systems, which we care about, but want to abstract away for application development.[4]
Reminding me very much of isolated turns in actor model terminology: “a turn is taking a waiting message, interpreting it, and deciding on both a state update for the actor and a collection of actions to take in response, perhaps sending messages or creating new actors.” ↩︎
This paper discusses how one may try to solve this and similar issues. ↩︎
Finally, we have the cross-controller case, which however is also relevant to the object system per se. ↩︎