Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behavior when the receiver successfully completes prior to message send #1300

Closed
lochana-chathura opened this issue Apr 9, 2024 · 5 comments
Assignees
Milestone

Comments

@lochana-chathura
Copy link
Member

lochana-chathura commented Apr 9, 2024

Description:
Consider the below code.

public function main() {
    worker w1 {
        1 ->> w2;
        2 ->> w2;
    }

    worker w2 {
        boolean b = true;

        int _ = <- w1;

        if b {
            return;
        }

        int _ = <- w1;
    }

    wait w1; // at the moment in jBallerina this code hangs when we have this wait statement
}

In the jBallerina implementation this scenario has not been handled. The issue is tracked in ballerina-platform/ballerina-lang#42476.

We were considering the following options as the expected behavior.

Option 1:
Similarly, for the non-error return case, we may need to propagate the info to the sender, that the receiver is not going to receive. How do we do that?

non-error return sample (click to expand)

When we have an error return, we propagate that error to the sender.

public function main() {
    worker w1 {
        1 ->> w2;
        error? unionResult = 2 ->> w2; // we enforce assignment here and get possible error assigned to a variable
    }

    worker w2 returns error? {
        boolean b = true;

        int _ = <- w1;

        if b {
            return error("error"); // error return
        }

        int _ = <- w1;
    }

    wait w1;
}

Option 2:
Just ignore the send value. However, in that scenario both the sender and receiver wouldn't know whether the sending was received by the other end.

Option 3:
We can make this an error like before as per the current spec.

"It is a compile time error if it is possible for a worker to terminate with success before it has executed all its receive actions."

When we have a possible non-error return before a receive-action we give a compile time error to the receive-action. Additionally receive-action will be disallowed inside a worker-on-fail-clause.

@lochana-chathura
Copy link
Member Author

lochana-chathura commented Apr 9, 2024

[1]

public function main() {

    worker w1 {
        boolean b = false;
        if b {
            () _ = 1 ->> function ;
        }

        () _ = 2 ->> function ;
    }

    int|error:NoMessage x = <- w1;
    io:println(x); // error NoMessage
    int y = <- w1;
    io:println(y); // 2
}

[2]

public function main() {
    worker w1 {
        boolean b = false;
        if b {
            () _ = 1 ->> function ;
        }

        () _ = 2 ->> function ;
    }

    int|error:NoMessage x = <- w1|w1;
    io:println(x); // 2
}

According to the behavior in [1] and [2], we do not propagate back the info on whether the send was received by the receiver. The sends will result in a nil value. Therefore, option 1 may not be necessary.

However, in [1] and [2] the receiver side knows the possibility of a no message error. In option 2 neither receiver has any idea regarding the communication for the original sample code. Kind of see an inconsistency there.

We need to finalize the behavior for Swan Lake Update 9. If deciding and implementing the right behavior takes some time, we could consider Option 3. (We have a PR for this already ballerina-platform/ballerina-lang#42478) It would allow us to change the behavior later on. Other options do not have that flexibility.

@lochana-chathura
Copy link
Member Author

CC: @hasithaa @MaryamZi @HindujaB

@jclark jclark changed the title Anticipated behavior when the receiver successfully completes prior to the sync send Behavior when the receiver successfully completes prior to message send Apr 15, 2024
@jclark
Copy link
Collaborator

jclark commented Apr 15, 2024

We have a similar problem with async send, because all async sends either are explicitly flushed or implicitly flushed on exit. See last two paragraphs of the "Send action" section.

@jclark jclark added this to the 2024R1 milestone Apr 15, 2024
@jclark
Copy link
Collaborator

jclark commented Apr 15, 2024

I think we should stick with the currently specified behavior (your Option 3), until we have something better.

This problem is independent of the changes we are making (#1273, #1274, #1277). Note that #1274 is just a convenience: even without that you can have the the received inside an on fail even without #1274).

Option 2 would be a significant change of philosophy and I don't think we have the justification for that.

There is some similarity with the alternate receive. I am wondering whether we can treat a receive that is skipped because of a control transfer to an on fail similar to receive that is skipped because it is an alternate (and another alternate succeeded). We could do Option 3 now, and then do something like this later (since Option 3 would make the receive inside on fail be a compile-time error).

@jclark
Copy link
Collaborator

jclark commented May 9, 2024

The fixes db9eec4 for #1273 address this.

@jclark jclark closed this as completed May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants