import ballerina/io;
import ballerina/runtime;
import ballerina/task;

// Defines a custom record type to use in the timer.
public type Person record {|
    string name;
    int age;
    int maxAge;
|};

public function main() {
    // The interval in which the timer should trigger.
    int intervalInMillis = 1000;

    // Initializes the timer scheduler using the interval value.
    // The delay will be equal to the interval as an initial delay is not provided.
    task:Scheduler timer = new ({
        intervalInMillis: intervalInMillis,
        initialDelayInMillis: 0
    });

    // Define a person object
    Person person = {name: "Sam", age: 0, maxAge: 10};

    // Attaching the service to the timer. This will not start the timer.
    // However, it will attach the service to the timer and also passes the
    // person object into the `onTrigger()` resource
    var attachResult = timer.attach(service1, person);
    if (attachResult is error) {
        io:println("Error attaching the service1.");
        return;
    }

    attachResult = timer.attach(service2, person);
    if (attachResult is error) {
        io:println("Error attaching the service2.");
        return;
    }

    // Starts the timer.
    var startResult = timer.start();
    if (startResult is error) {
        io:println("Starting the task is failed.");
        return;
    }

    // While loop will stop the function from exiting until the service ends.
    while (person.age < person.maxAge) {
        // Waits until the age of the person reaches the max age.
        runtime:sleep(2000);
    }

    runtime:sleep(1000);

    // Cancels the timer. This will stop the timer and all the services
    // attached to it.
    var stopResult = timer.stop();
    if (stopResult is error) {
        io:println("Stopping the task is failed.");
        return;
    }

    io:println("End.");
}

// The service, which will be attached to the timer.
service service1 = service {
    // The onTrigger resource, which will trigger when the timer runs off.
    // The usage of the Person object being passed inside the function, which we
    // attached with the timer.
    resource function onTrigger(Person person) {
        if (person.age < person.maxAge) {
            person.age = person.age + 1;
            io:println("Hi " + person.name + " you are " + person.age.toString() + " years old now.");
        }
    }
};

service service2 = service {
    resource function onTrigger(Person person) {
        if (person.age == 5) {
            io:println(person.name + " started schooling");
        }
    }
};

Task Scheduler Timer

A Task scheduler can be used to create timers to trigger periodically. A service can be attached to the task Scheduler object using the attach() function and the Listener can be started using the start() function. The service that is being attached must contain the onTrigger() resource function. Additionally, a user can pass a set of any values to the resource using the attach() function, which then can be used inside the onTrigger() function. The Listener can be stopped by calling the stop() function.

import ballerina/io;
import ballerina/runtime;
import ballerina/task;
public type Person record {|
    string name;
    int age;
    int maxAge;
|};

Defines a custom record type to use in the timer.

public function main() {
    int intervalInMillis = 1000;

The interval in which the timer should trigger.

    task:Scheduler timer = new ({
        intervalInMillis: intervalInMillis,
        initialDelayInMillis: 0
    });

Initializes the timer scheduler using the interval value. The delay will be equal to the interval as an initial delay is not provided.

    Person person = {name: "Sam", age: 0, maxAge: 10};

Define a person object

    var attachResult = timer.attach(service1, person);
    if (attachResult is error) {
        io:println("Error attaching the service1.");
        return;
    }

Attaching the service to the timer. This will not start the timer. However, it will attach the service to the timer and also passes the person object into the onTrigger() resource

    attachResult = timer.attach(service2, person);
    if (attachResult is error) {
        io:println("Error attaching the service2.");
        return;
    }
    var startResult = timer.start();
    if (startResult is error) {
        io:println("Starting the task is failed.");
        return;
    }

Starts the timer.

    while (person.age < person.maxAge) {

While loop will stop the function from exiting until the service ends.

        runtime:sleep(2000);
    }

Waits until the age of the person reaches the max age.

    runtime:sleep(1000);
    var stopResult = timer.stop();
    if (stopResult is error) {
        io:println("Stopping the task is failed.");
        return;
    }

Cancels the timer. This will stop the timer and all the services attached to it.

    io:println("End.");
}
service service1 = service {

The service, which will be attached to the timer.

    resource function onTrigger(Person person) {
        if (person.age < person.maxAge) {
            person.age = person.age + 1;
            io:println("Hi " + person.name + " you are " + person.age.toString() + " years old now.");
        }
    }
};

The onTrigger resource, which will trigger when the timer runs off. The usage of the Person object being passed inside the function, which we attached with the timer.

service service2 = service {
    resource function onTrigger(Person person) {
        if (person.age == 5) {
            io:println(person.name + " started schooling");
        }
    }
};
# To run this sample, navigate to the directory that contains the
# `.bal` file, and execute the `ballerina run` command below.
ballerina run task_scheduler_timer.bal
Hi Sam you are 1 years old now.
Hi Sam you are 2 years old now.
Hi Sam you are 3 years old now.
Hi Sam you are 4 years old now.
Hi Sam you are 5 years old now.
Hi Sam you are 6 years old now.
Sam started schooling
Hi Sam you are 7 years old now.
Hi Sam you are 8 years old now.
Hi Sam you are 9 years old now.
Hi Sam you are 10 years old now.
End.

A scheduler can have any number of services attached to it. All the attached services will run when the scheduler triggers them. A Person record is attached to the Scheduler when attaching the service. It is then passed into the resource functions of the service. When the age of the person reaches the maxAge, the while loop is returned. Hence the task is stopped.