import ballerina/io;function main (string[] args) {
    fork {
        worker w1 {
            int i = 23;
            string s = "Colombo";
            io:println("[w1] i: " + i + " s: " + s);
            i, s -> fork;
        }        worker w2 {
            float f = 10.344;
            io:println("[w2] f: " + f);
            f -> fork;
        }    } join (all) (map results) {
        any[] resW1 = check <any[]>results["w1"];
        int iW1 = check <int>resW1[0];
        string sW1 = <string>resW1[1];
        io:println("[join-block] iW1: " + iW1 + " sW1: " + sW1);
        any[] resW2 = check <any[]>results["w2"];
        float fW2 = check <float>resW2[0];
        io:println("[join-block] fW2: " + fW2);
    }
}

Fork/Join

In a function execution, a fork-join statement splits the current execution to multiple workers, do their work in parallel, and join the executions together to process their results. The fork block allows you to start any number of parallel workers at once. The join block gets the results from the workers that are running in parallel. You can make the join block wait for all the workers to finish their execution using the 'all' condition, wait for a specific number of workers to finish execution, or provide a time-out for joining the workers. Once the join block receives the required results, you can define how you want to use the results.

import ballerina/io;
function main (string[] args) {
    fork {
        worker w1 {
            int i = 23;
            string s = "Colombo";
            io:println("[w1] i: " + i + " s: " + s);

The fork-join allows developers to spawn (fork) multiple workers within a ballerina program, join the results of those workers, and execute code on joined results. In this example, you are forking worker w1 and w2.

            i, s -> fork;
        }

The reply to the join block from worker w1.

        worker w2 {
            float f = 10.344;
            io:println("[w2] f: " + f);
            f -> fork;
        }

The reply to the join block from worker w2.

    } join (all) (map results) {

The ‘all’ condition makes the join block wait until all the workers have sent in their replies. Once all the workers have replied, the replies are stored in the ‘result’ variable as a map.

        any[] resW1 = check <any[]>results["w1"];
        int iW1 = check <int>resW1[0];
        string sW1 = <string>resW1[1];
        io:println("[join-block] iW1: " + iW1 + " sW1: " + sW1);

Get the values received from worker ‘w1’.

        any[] resW2 = check <any[]>results["w2"];
        float fW2 = check <float>resW2[0];
        io:println("[join-block] fW2: " + fW2);
    }
}

Get the values received from worker ‘w2’

$ ballerina run fork-join.bal
[w1] i: 23 s: Colombo
[w2] f: 10.344
[join-block] iW1: 23 sW1: Colombo
[join-block] fW2: 10.344