Multiple event actions at Join Node allowed - uml

Is it allowed to use multiple events at a join node, like shown below.
Or is the imaginary token, that can be used to describe an activity flow, just one moment there and gone before the second events appears?

Is it allowed to use multiple events at a join node
Yes, a JoinNode is a ControlNode that synchronizes multiple flows.
is the imaginary token, that can be used to describe an activity flow, just one moment there and gone before the second events appears
The token offered on the incoming edges are blocked while the join is not passing, the moment a JoinNode is passing depends on its joinSpec :
If a JoinNode does not have a joinSpec, then this is equivalent to a joinSpec Expression with the Boolean operator “and.” That is, the implicit default joinSpec condition is that there is at least one token offered on each incoming ActivityEdge
Else the joinSpec it is a ValueSpecification determining the condition under which the join will emit a token, and then not necessary when at least a token is offered on each incoming ActivityEdge. This ValueSpecification is evaluated whenever a new token is offered to the JoinNode on any incoming ActivityEdge.
For more here is a copy of the §15.3.3.4 Join Nodes page 389 of formal/2017-12-05:
A JoinNode is a ControlNode that synchronizes multiple flows. A JoinNode shall have exactly one outgoing
ActivityEdge but may have multiple incoming ActivityEdges. If any of the incoming edges of a JoinNode are
ObjectFlows, the outgoing edge shall be an ObjectFlow. Otherwise the outgoing edge shall be a ControlFlow.
Join nodes may have a joinSpec, which is a ValueSpecification that determines the condition under which the join will
emit a token.
If a JoinNode has a joinSpec, then this ValueSpecification is evaluated whenever a new token is offered to
the JoinNode on any incoming ActivityEdge. This evaluation shall not be interrupted by any new tokens offered during
the evaluation, nor shall concurrent evaluations be started when new tokens are offered during an evaluation. The
ValueSpecification shall evaluate to a Boolean value.
If the joinSpec ValueSpecification is given by a textual expression, then the names of the incoming edges may be used to
denote a Boolean value indicating the presence (true) or absence (false) of an offer from a ControlFlow or to denote the
value associated with an object token offered from an ObjectFlow (if any). Alternatively, the joinSpec may consist of an
Expression with the name of a single Boolean operator and no operands specified. In this case, the value of the joinSpec
shall be given by applying the given operator to Boolean values indicating the presence (true) or absence (false) of
offers on each incoming edge (with the ordering of the operands not specified).
If a JoinNode does not have a joinSpec, then this is equivalent to a joinSpec Expression with the Boolean operator “and.”
That is, the implicit default joinSpec condition is that there is at least one token offered on each incoming ActivityEdge.
If the (implicit or explicit) joinSpec of a JoinNode evaluates to true, then tokens are offered on the outgoing ActivityEdge
of the JoinNode according to the following rules:
If all the tokens offered on the incoming edges are control tokens, then one control token is offered on the
outgoing edge.
If some of the tokens offered on the incoming edges are control tokens and others are object tokens, then only
the object tokens are offered on the outgoing edge. Tokens are offered on the outgoing edge in the same order
they were offered to the join. If isCombinedDuplicate is true for the JoinNode, then before object tokens are
offered to the outgoing edge, those containing objects with the same identity are combined into one token.
The above rules apply to all tokens offered to the JoinNode, including multiple tokens offered from the same incoming
edge.
If any tokens are offered to the outgoing ActivityEdge of a JoinNode, they shall be accepted by the target or rejected for
traversal over the edge (e.g., due to a failed guard) before any more tokens are offered to the outgoing edge. If tokens are
rejected for traversal, they shall no longer be offered to the outgoing edge. A conforming implementation may omit
unnecessary joinSpec evaluations if the JoinNode is blocked from offering tokens on its outgoing edge.

Related

Modelling inter thread communication in activity diagram

I am trying to model an application which runs multiple concurrent flows.
In this situation multiple threads can create events and store them in a buffer which are then collected and displayed by another thread. The receiving thread is supposed to block and wait for incoming events.
I have currently modelled it like this:
This example uses object flows. However I am not sure if this is the correct way to model this type of inter thread communication.
The other option I was looking at is using signals but I'm not sure about that either.
Any help would be appreciated.
Every activity requires all tokens to be offered before it can start. You will have to use a buffer node as a queue.
Object flows capture inter thread communication well.
You could also use signals, if you want to be more specific and your system uses in fact messages.
There is one problem in your diagram though: The Display Event action consumes all offered control tokens and one object token on each invocation. I can‘t tell from your diagram, but probably there is only one control token. That means, the action will only run once. The solution is, to delete the control flow. The action then starts for each incoming object token.
Each output pin acts as a local buffer. If tokens are generated faster than the event can be displayed, tokens will potentially pile up in multiple pins. In this case it is undefined which pin will be the source of the next token. This is not necessarily a problem, but if tokens shall be processed in chronological order, you need to use a central buffer. The symbol is a rectangle with the keyword «central buffer»

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
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) :
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?
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:
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.
[...]
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.

Join Node or Merge Node?

I am trying to make an activity diagram of a user for my system and I am unsure if the flow should come down to a Join Node or Merge Node before the user can log off. Here is the one I have made sa of now. Could anyone explain to me what's the difference?
It must be a join (though I first remembered wrongly and thanks to #AxelScheithauer pointing out my error). P. 401 of UML 2.5
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. That is, there is an implicit fork of the flow of control from the ExecutableNode to its outgoing ControlFlows.
That means that all 6 actions below will start in parallel which does not mean they must run concurrently. But all of them need completion in order to continue after the join below. (I doubt that this is desired.)
There's a (double) 2nd flaw in the top decision back-flows. They need to go back to the top merge. Otherwise neither Login nor Register would start since they expect 3 or 2 tokens where only one would arrive.

Activity Diagram - confusion regarding fork/join and decision/merge in this scenario

I am creating an activity diagram
Admin log in to the web
If validated, it reaches the dashboard
Through dashboard it can manage account, manage product and manages issues
after performing one of above options, it can go back to dashboard or logout from system.
I have used fork/join, is it correct or I should be using decision/merge instead
2ndly, is the procedure of logging out or performing another option available in dashboard correctly defined?
Your activity is having several issues.
First and most severe, it will not do anything because actions (and mostly those - not all model elements in activities) having an "implicit and sematics" for incomming control flows. This means that an action is only executed when an token is offered on ALL incomming control flow actions, otherwise it waits. So as your control flow from validate can not offer an token before Login has been executed and finished, you are having a lock. And nothing is executed. The same applies to Dashboard. To solve this you need to model merge nodes.
The second point is that you only want to execute (according to your description) one of the manage actions. (Btw. names with generic verbs like "manage", "maintain", "do", "perform", etc. are quite bad names for actions, use more specific ones instead). Your model executes, irregardless of the selection in the dashboard action, all manage actions concurrently. Concurrently means in an arbitrary order and does not demand a parallel execution. Thus you should replace the fork with a decision node, where the conditions on the outgoing flows are based on the selection from the dashboard. An decision node can have an arbitrary (but finite) number of outgoing control flows. All the outgoing control flows from the manage actions are merged using a merge node instead of a join node. As the join node would wait for an incommingtoken per incomming control flow.
A minor point, that would be solved when using an UML/SysML tool is that the fork and join nodes are bars and not rectangular frames.
Your AD has 2 flaws. First a fork/join is a solid thick line, but not a hollow rectangle. Second, it's used wrongly. This way you run all Manage actions in parallel and continue when they are all finished. According to your description use a diamond to decide for one of the actions Also use the diamond afterwards to merge the flows and continue to Logout.

Activity Diagram how to continue code flow in one chart

I have a function.
Which for example goes like this:
Function start:
...
if statement{
set variable
}
if second if{}
contintue
This code I try to put into a UML, Activity diagram.
I wondered if my forking is done right, or do I need to use a forking symbol. So I have a split where it eventually gets into the if statement ( difference in totals). But after the if (or even if the if is not even executed) the next if statement will be executed (regardless of first if result).
If you want to have conditional paths you need to use decision nodes. Imagine a virtual token to represent the execution flow. When you are at an action that has multiple (unguarded) control flows leaving it, each will take a token (the UML spec calls that implicit fork) an execution will continue in parallel. So either you add guards to each of the outgoing control flows or you use a decision node. Though you should (or better must) use guards here too you have only a single token that will leave the decision node. Without proper guards it will be undecided which of the outgoing flows will take the token.
Implicit fork:
Only one token continues:
One token for sure and eventually a 2nd in parallel:
(I'm not 100% sure if that's really true. It's a notation I'd never use.)
Only one token continues, but not defined which (due to no guards):

Resources