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

Viewed 56

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?

2 Answers

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.

It seems like you missed the point that object tokens are sufficient to trigger an action - without any need for a control token.

UML 2.5 p. 374:

15.2.3.4 Object Flows

Object tokens pass over ObjectFlows, carrying data through an Activity via their values, or carrying no data ( null tokens). A null token can still be passed along an ObjectFlow and used like any other token. For example, an Action can output a null token to explicitly indicate that it did not produce an optional value, and a downstream DecisionNode (see sub clause 15.3) can test for this and branch accordingly.

So once you get rid of the start node and the superfluous control structures you will get the desired behavior: the action starts with receiving an object and ends when emitting the resulting object.

I could not find a full fledged example on the fly, but that picture illustrates it well enough:

enter image description here

Longer explanation

P. 478 of UML 2.5: (please look into the specs for more details)

16.12 Expansion Regions

16.12.1 Summary

An ExpansionRegion is a StructuredActivityNode that executes its contained elements multiple times corresponding to elements of an input collection.

[...]

16.12.3 Semantics

An ExpansionRegion is a StructuredActivityNode that takes as input one or more collections of values and executes its contained ActivityNodes and ActivityEdges on each value in those collections. If the computation produces results, these may be collected into output collections. The number of output collections can differ from the number of input collections.

[...]

16.12.4 Notation

An ExpansionRegion is shown as a dashed rounded box with one of the keywords «parallel», «iterative» or «stream» in the upper left corner (see Figure 16.48). Input and output ExpansionNodes are drawn as small rectangles divided by vertical bars into small compartments.

[...]

enter image description here

As you can see, the expansion region is a "simple" action that takes an object and returns another. As such it's like any simple action with an input pin like shown above in my answer. That means it will start upon receipt of an object and emit an (eventually empty) object when it's done.

Related