diff --git a/examples/alternate-receive/alternate_receive.bal b/examples/alternate-receive/alternate_receive.bal new file mode 100644 index 0000000000..4c2c9cb13c --- /dev/null +++ b/examples/alternate-receive/alternate_receive.bal @@ -0,0 +1,60 @@ +import ballerina/http; +import ballerina/io; +import ballerina/lang.runtime; + +type Response record { + record { + string 'worker; + } args; +}; + +// Concurrently fetch content from two URLs using workers and +// return the first non-error value received. +function getFirstFetched(string url1, string url2) returns string? { + // Workers `w1` and `w2` fetch content from `url1` and `url2` respectively. + worker w1 { + string|error result = fetch(url1); + result -> w3; + } + + worker w2 { + runtime:sleep(3); + string|error result = fetch(url2); + result -> w3; + } + + // Worker `w3` waits until one of the workers sends a non-error value. + worker w3 returns string? { + // The value of the variable `result` is set as soon as + // a non-error message is received from either worker `w1` or `w2`. + string|error result = <- w1 | w2; + return result is error ? () : result; + } + + // The value returned from worker `w3` is set to the variable `w3Result`. + string? w3Result = wait w3; + return w3Result; +} + +function fetch(string url) returns string|error { + http:Client cl = check new (url); + Response response = check cl->get(""); + return response.args.'worker; +} + +public function main() { + // Both arguments passed to the `getFirstFetched` function are valid URLs. + // Thus, the alternate receive action in worker `w3` sets the + // first value it receives from a worker as the result. + string? firstFetched = getFirstFetched("https://postman-echo.com/get?worker=w1", + "https://postman-echo.com/get?worker=w2"); + io:println(firstFetched); + + // The first argument passed to the `getFirstFetched` function is an invalid URL. + // Therefore, the worker `w1` in the `getFirstFetched` function returns an error. + // Thus, the alternate receive action in worker `w3` waits further + // and sets the value that is received from `w2` as the result. + firstFetched = getFirstFetched("https://postman-echo.com/ge?worker=w4", + "https://postman-echo.com/get?worker=w5"); + io:println(firstFetched); +} diff --git a/examples/alternate-receive/alternate_receive.md b/examples/alternate-receive/alternate_receive.md new file mode 100644 index 0000000000..9c78b50f65 --- /dev/null +++ b/examples/alternate-receive/alternate_receive.md @@ -0,0 +1,7 @@ +# Alternate receive + +The alternate receive action can be used to receive one of multiple values corresponding to multiple send actions. It operates by waiting until it receives a non-error message, a panic termination status on a closed channel, or the closure of all channels. The alternative receive action sets the first non-error value it receives as the result. If all the channels return errors, it sets the last received error as the result. + +::: code alternate_receive.bal ::: + +::: out alternate_receive.out ::: diff --git a/examples/alternate-receive/alternate_receive.metatags b/examples/alternate-receive/alternate_receive.metatags new file mode 100644 index 0000000000..078efcb206 --- /dev/null +++ b/examples/alternate-receive/alternate_receive.metatags @@ -0,0 +1,2 @@ +description: This BBE demonstrates the use of the alternate receive action in inter-worker communication +keywords: ballerina, ballerina by example, bbe, worker, alternate receive diff --git a/examples/alternate-receive/alternate_receive.out b/examples/alternate-receive/alternate_receive.out new file mode 100644 index 0000000000..69a8462f90 --- /dev/null +++ b/examples/alternate-receive/alternate_receive.out @@ -0,0 +1,3 @@ +$ bal run alternate_receive.bal +w1 +w5 diff --git a/examples/index.json b/examples/index.json index b2b43e811a..3acba6736b 100644 --- a/examples/index.json +++ b/examples/index.json @@ -1475,6 +1475,13 @@ "verifyOutput": true, "isLearnByExample": true }, + { + "name": "Alternate receive", + "url": "alternate-receive", + "verifyBuild": true, + "verifyOutput": true, + "isLearnByExample": true + }, { "name": "Multiple receive", "url": "multiple-receive",