Search code examples
umlactivity-diagram

How ExpansionRegion of mode stream can be terminated when all items are processed?


Consider the simplest ExpansionRegion of mode stream. According to UML Documentation (16.12 Expansion Regions)

If the value [of mode] is stream, there is exactly one expansion execution, and element values are offered to this execution in a stream from each collection. That is, each element of a collection on an input ElementNode is offered separately as a token, one by one, on all outgoing ActivityEdges from the ExpansionNode

enter image description here

But this ExpansionRegion will never end! As soon as all tokens from input ExpansionNode are processed, Do something will be waiting indefinitely for a token from input, which will never come! How do I terminate this ExpansionRegion?

Update: it seems the only solution I could find is the following (but I'm not sure, see below) :

enter image description here

When there are no more tokens available from input then the control token from Do something is not accepted by Do something through C.3-C.4-C.2 path since according to 16.2.3.4 Actions and Pins in Activities

Executing an Action in an Activity requires all of its InputPins to be offered all necessary tokens, as specified by their minimum multiplicity

and according to 15.2.3.2 Activity Nodes

When an ActivityNode begins execution, tokens are accepted from some or all of its incoming ActivityEdges and a token is placed on the node.

so it seems reasonable to conclude from the above that Action (i.e. Do something) will not accept a control token if it is not able to execute so Decision node will pass the token to control flow C.5 since it has "else" guard and according to 15.3.3.6 Decision Nodes:

For use only with DecisionNodes, a predefined guard “else” represented as an Expression with “else” as its operator and no operands) may be used for at most one outgoing edge. This guard evaluates to true only if the token is not accepted by any other outgoing edge from the DecisionNode.

Update 2: Is the loop (C.1-C.2-C.3) required? It seems to me the answer is "yes" because without it Do something would process just one object token! I.e. Do something would receive a single control token at the ExpansionRegion's invocation according to 15.2.3.6 Activity Execution

When an Activity is first invoked, none of its nodes other than input ActivityParameterNodes will initially hold any tokens. However, nodes that do not have incoming edges and require no input data to execute are immediately enabled. A single control token is placed on each enabled node and they begin executing concurrently. Such nodes include ExecutableNodes (see sub clause 15.5) with no incoming ControlFlows and no mandatory input data and InitialNodes (see sub clause 15.3).

and according to 15.5.3.1 Executable Nodes

When an ExecutableNode completes an execution, the control token representing that execution is removed from the ExecutableNode and control tokens are offered on all outgoing ControlFlows of the ExecutableNode.

Are there any clarification in UML Documentation saying that control token could "stay" on Do something (without the loop) and re-enable its execution to process next object token?


Solution

  • You seem to think that you modeled a deadlock. Actually, UML Activities cannot have deadlocks by definition. The execution of all action containers (Activitys and StructuredActivityNodes with their subtypes) ends when none of the contained actions is enabled.

    StructuredActivityNode: A StructuredActivityNode completes execution according to the same rules as for the completion of the execution of an Activity, including terminating execution due to an ActivityFinalNode.

    Activity: The execution of an Activity with no streaming Parameters completes when it has no nodes executing and no nodes enabled for execution, or when it is explicitly terminated using an ActivityFinalNode.

    After processing the last element in the input collection, no action is enabled anymore and therefore, the expansion region ends and offers the output collection to the outgoing object flow. Therefore, the initial node and all the control flows are not needed.

    Having said that, it is possible, that you need control flows, because you have additional actions. Let's say you need to initialize the system before the first execution and Do something else after each execution of Do something. Your first example works well for this. Just place initialize on C.1 and Do something else on C.3.

    Your second solution could be used, if you have to do some cleanup before leaving the expansion region. Just place it on C.5. I was not aware, that this would work, but after rereading the specification text cited by you, I agree that it is working.