Wrong messages might be code generated

Issue #425 resolved
Matthias Schoettle created an issue

I experienced this in the Workflow concern in the following case:

WorkflowUtility defines getCurrentExecutor as follows:

getCurrentExecutor.png

Also, the methods SequenceNode.depositToken and ControlFlowNode.depositToken call it. These methods are defined as follows:

depositToken2.png

depositToken1.png

The result of the code generation, however, might look like this:

    static WorkflowExecutor getCurrentExecutor() {
        for (int i = 0; i < numberOfActivations; i++) {
            this.workflowNode = toActivate.get(this.i);
            if (i == numberOfActivations) {
                currentExecutor.scheduleNextNode(this.workflowNode);
            } else {
                WorkflowUtility.spawnExecution(this.workflowNode, c);
            }
        }
    }

As you can see, this is the part after the call to getCurrentExecutor from ControlFlowNode.depositToken. Sometimes, the code is correctly generated as defined in the message view, but sometimes it is not.

Comments (10)

  1. Matthias Schoettle reporter

    It seems that getMessagesForOperation(op : Operation) in *commonHelpers.mtl` finds two messages in this case. Since it is converted to a set, I think the order depends and hence produces different results.

    I have the feeling that this query is implemented in this way, because of nested behaviour.

  2. Matthias Schoettle reporter

    Tracking it further down:

    getMessagesForOperation uses getMessageFragments, which searches for all fragments after the receive event. In the above case, there is the message spawnExecution inside the CombinedFragment. It does find this fragment (erroneously) and hence that call is considered.

    If I am not mistaken, if there is nested behaviour, there is for certain a reply message (even for void methods). What is necessary is to make sure that this reply message exists. The getMessageFragments query actual finds so called separatorFragments (send event of reply message), however, in the case of no such fragment being found it uses all subsequent fragments on that lifeline.

  3. Matthias Schoettle reporter

    References #425: Ensures that no message fragments are returned if no separator fragment has been found.

    In case no separator fragment is found (reply message of the message or incoming message), no fragments should be returned. Therefore, the index will be set to 0.

    → <<cset ac3522d51d9e>>

  4. Matthias Schoettle reporter

    The above fix, however, does not prevent the following case:

    Screen Shot 2016-03-02 at 12.01.53.png

    This is mainly a problem of how it is implemented. For instance, the index of fragments on the lifeline is not considered. However, I suggest that the second condition of the following is removed. This would mean that nested behaviour always ends with a reply message (even for void operations), just like the message view itself always has a reply message.

    let message : Message = f.oclAsType(MessageEnd).message in
        (message.messageSort = MessageSort::reply and f = message.sendEvent and m.signature = message.signature) or
        (message.messageSort <> MessageSort::reply and not message.selfMessage and f = message.receiveEvent)
    
  5. Matthias Schoettle reporter

    Since there are many message views with no reply messages for nested behaviour, I am leaving the second condition in the code generator to still support it.

  6. Matthias Schoettle reporter

    References #425: Updates condition for fragment creation after the send event.

    Void operations also have a reply message if their message view is not defined.

    → <<cset 20485d1268d1>>

  7. Log in to comment