import ballerina/io;
function main (string[] args) {
    int i = 100;
    string s = "WSO2";
    map m = {"name":"Abhaya", "era":"Anuradhapura"};
    fork {
        worker W1 {
            i = 23;
            m["name"] = "Rajasinghe";
            string n = "Colombo";
            i, n -> fork;
        }        worker W2 {
            s = "Ballerina";
            m["era"] = "Kandy";
            s -> fork;
        }
    } join (all) (map results) {        any[] r1;
        any[] r2;
        var x1 = <any[]>results["W1"];
        match x1 {
            any[] val  => {r1 = <any[]> val;}
            error e => {io:println(e.message);}
        }
        var x2 = <any[]>results["W2"];
        match x2 {
            any[] val  => {r2 = <any[]> val;}
            error e => {io:println(e.message);}
        }
        int p;
        p = check <int>r1[0];
        string l;
        var indexL = <string>r1[1];
        match indexL {
            string val  => {l = <string > val;}
        }
        string q;
        var indexQ = <string>r2[0];
        match indexQ {
            string val  => {q = <string > val;}
        }
        io:println("[default worker] within join:
        Value of integer from W1 is [" + p + "]");
        io:println("[default worker] within join:
        Value of string from W1 is [" + l + "]");
        io:println("[default worker] within join:
        Value of string from W2 [" + q + "]");
    }
    io:println("[default worker] after fork-join:
        Value of integer variable is [" + i + "]
        Value of string variable is [" + s + "]");
    string name;
    string era;    var varName = <string>m["name"];
    match varName {
        string val  => {name = <string > val;}
    }    var varEra = <string>m["era"];
    match varEra {
        string val  => {era = <string > val;}
    }    io:println("[default worker] after fork-join:
        Value of name is [" + name + "]
        Value of era is [" + era + "]");
}

Fork/Join Variable Access

Workers within a fork-join can access the variables that are declared within the scope of that statement. The variables can be value type variables or reference type variables. Value type variables, such as string, integer, float, and blob type variables, are passed into the workers as a copy of the original data. Therefore, you are able to update the value of it within the worker and that value is only defined within the specific worker. Reference type variables, such as map, json, xml, and records type variables, are passed into these workers as a reference to the original data. Therefore, if you update the value of these variables within a worker, the value gets updated for the entire function. The Join block receives a map of any type array, which contains the data sent from the respective workers.

import ballerina/io;
function main (string[] args) {

The in scope variables can be accessed by the workers in the fork-join statement.

    int i = 100;
    string s = "WSO2";
    map m = {"name":"Abhaya", "era":"Anuradhapura"};

These variables can be accessed by the forked workers.

    fork {
        worker W1 {

Declare the fork-join statement.

            i = 23;

Change the value of the integer variable ‘i’ within the worker W1.

            m["name"] = "Rajasinghe";

Change the value of map variable ’m’ within the worker W1.

            string n = "Colombo";

Define a new variable within the worker to send to the join block.

            i, n -> fork;
        }

Send the data to the join block of the fork-join from worker W1.

        worker W2 {
            s = "Ballerina";

Change the value of string variable ’s’ within the worker W2.

            m["era"] = "Kandy";

Change the value of map variable ’m’ within the worker W2.

            s -> fork;
        }
    } join (all) (map results) {

Send the data to the join block of the fork-join from worker W2.

        any[] r1;
        any[] r2;
        var x1 = <any[]>results["W1"];
        match x1 {
            any[] val  => {r1 = <any[]> val;}
            error e => {io:println(e.message);}
        }

Declare variables to receive the results from the forked workers W1 and W2. The ‘results’ map contains a map of any type array from each worker defined within the fork-join statement Values received from worker W1 are assigned to the ‘any’ type array of r1.

        var x2 = <any[]>results["W2"];
        match x2 {
            any[] val  => {r2 = <any[]> val;}
            error e => {io:println(e.message);}
        }

Values received from worker W2 are assigned to ‘any’ type array of r2.

        int p;
        p = check <int>r1[0];

Get the 0th index of the array returned from worker W1.

        string l;
        var indexL = <string>r1[1];
        match indexL {
            string val  => {l = <string > val;}
        }

Getting the 1st index of the array returned from worker W1.

        string q;
        var indexQ = <string>r2[0];
        match indexQ {
            string val  => {q = <string > val;}
        }

Getting the 0th index of the array returned from worker W2.

        io:println("[default worker] within join:
        Value of integer from W1 is [" + p + "]");
        io:println("[default worker] within join:
        Value of string from W1 is [" + l + "]");
        io:println("[default worker] within join:
        Value of string from W2 [" + q + "]");
    }

Print the values received from workers within the join block.

    io:println("[default worker] after fork-join:
        Value of integer variable is [" + i + "]
        Value of string variable is [" + s + "]");

Print the values after the fork-join statement to check the values of the variables. The value type variables have not changed since they are passed in as a copy of the original variable.

    string name;
    string era;

The reference type variables have got updated since they are passed in as a reference to the workers.

    var varName = <string>m["name"];
    match varName {
        string val  => {name = <string > val;}
    }
    var varEra = <string>m["era"];
    match varEra {
        string val  => {era = <string > val;}
    }
    io:println("[default worker] after fork-join:
        Value of name is [" + name + "]
        Value of era is [" + era + "]");
}
$ ballerina run fork-join-variable-access.bal
[default worker] within join:
      Value of integer from W1 is [23]
[default worker] within join:
      Value of string from W1 is [Colombo]
[default worker] within join:
      Value of string from W2 [Ballerina]
[default worker] after fork-join:
      Value of integer variable is [100]
      Value of string variable is [WSO2]

The value type variables have not changed since they are passed in as a copy of the original variable.

[default worker] after fork-join:
      Value of name is [Rajasinghe]
      Value of era is [Kandy]

The reference type variables have got updated since they are passed in as a reference to the workers.