Question

In an UML activity diagram, join nodes synchronise concurrent flows by regulating the flow of tokens. The UML specifications foresees that tokens can be rejected. Section 15.3.3.4 Join Nodes says:

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.

But it does not clearly determine what can reject token. For example selection behavior and weight property of outgoing edge and also acceptance of target node (includes it's precondition) can force a token to wait before traversing. Which ones can reject traversing?

Also above quote says:

... before any more tokens are offered to the outgoing edge

Does it mean when a token is rejected for traversal, it immediately will be withdrawn (and destroyed) ? Or may it wait until the next token is prepared and when that next token be offered, older one will be destroyed?

For example in below diagram, what will happen if left JoinNode receives tokens from branches b1 and b2 and creates token b but token a be not created yet? Does b wait for a? Or it will be withdrawn? And if it waits, what will happen if left join node creates another token before a is offered to the right JoinNode?

diagram

Was it helpful?

Solution

The quote mentions not just rejected but rejected for traversal over the edge. This corresponds to the case that a token is not allowed to go through an edge, and not to the case where a target may not accept it.

In which case is it rejected for traversal ?

Unfortunately, unlike the terms offered and accepted which are well defined, the term rejected is not explicitly defined and need to be interpreted.

To my knowledge it can happen only in the case of a guard, as described in 15.2.3.3:

An ActivityEdge may have a guard, which is a ValueSpecification that is evaluated for each token offered to the edge. An offer shall only pass along an ActivityEdge if the guard for the edge evaluates to true for the offered token.

In which case is it not rejected for traversal ?

For weight, there is no rejected traversal. The tokens are accumulated in the source until the threshold is reached. In case a guard blocks a token, it's not the traversal that fails but the offer:

If the guard fails for any of the tokens, and this reduces the number of tokens that can be offered to the target to less than the weight, then all the tokens fail to be offered.

For selection there's also no rejection of a traversal, but a delay on acceptance (15.2.3.4) :

selection Behavior is used while offering tokens to the target node, it may be run many times on the same token before the token is accepted by the target node.

Additional remarks on 15.3.3.4 and resolution of your scenario

The following statement tells us that in case of a rejected traversal, the token is definitively withdrawn:

If tokens are rejected for traversal, they shall no longer be offered to the outgoing edge.

The following statement tells us that unless a token is rejected for traversal, it will wait until it is accepted by the target (the acceptance doesn't need to be immediate):

They shall be accepted by the target or rejected for traversal over the edge

Consequence: In your scenario, b will wait for a and they will both together be consumed to generate an output token of the right join node.

And finally, this sentence explains that in case of successful traversal, the tokens are sent sequentially, one by one:

before any more tokens are offered to the outgoing edge

Consequence: In your scenario, as long as b will wait for an a, no new b will be offered by the left join.

Edit: Isn't there an issue with the UML spec here ?

The "one by one" rule doesn't seem fully consistent IMHO:

  • The rule is written about the offering part on the output, not the consumption part of the input. This makes the behavior in case of a weight on the output extremely ambiguous: I'd avoid it.
  • The rule seems to be written with control tokens in mind. It is not clear to me what happens if 2 different object tokens are on the input (or 2 replicated objects without the CombinedDuplicates): I'd expect all of them to pass the join. But what hapens if one of it gets rejected: would the other continue its way alone ?

Similarly, IMHO the rejection on traversal logic seems not to cover all the cases. For example, what if the output edge goes to a decision node (so it is not rejected), but none of the subsequent guarded branch can accept it ? Shall we understand that the token is rejected (implicitly the decision input would be guarded by the combination of all possible output), or shall we consider it's consumed and the token is waiting in the decision node ?

So I think there is still some work to do for the standard committee in this area.

OTHER TIPS

I think the problem with your picture is that you are trying to do something superficial. The edge b is absolutely superfluous. Actually what you would do is to directly join the tokens in one place:

enter image description here

Tokens will wait in Action and the ones sending b1 and b2.

You question is a sophism since the facts are wrong. Like

The village barber shaves all men in the village that don't shave themselves. Does he shave himself or not?

If you think a moment you find that the thesis is just not right. So any discussion around it is meaningless.

I read Christophe's answer and related parts of specification multiple times until now and describe what I understand.

At first I attempt to second part of my question:

Does it mean when a token is rejected for traversal, it immediately will be withdrawn (and destroyed) ? Or may it wait until the next token is prepared and when that next token be offered, older one will be destroyed?

As Christophe said, this statement can be interpreted that "a token can wait":

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.

But there is a question: "Where can arrived token wait?"

  • not in JoinNode (specification says only FinalNode of control nodes can hold a token)
  • not in outgoing edge (specification says only outgoing edge of ForkNode can hold tokens)

So I conclude: "When a token offers to outgoing edge of JoinNode, it must immediately traverse to downstream node of edge or it will be rejected (and shall no longer be offered to the outgoing edge)." Thus in diagram of question, b does not wait for a.

In about first part of my question, I think when a token cannot wait, using non default weight will be irrational and a token may be rejected by either of guard or selection or precondition of target node.

Licensed under: CC-BY-SA with attribution
scroll top