Tasks

Defining a task is a simple as annotating a method

Introduction

A task is the work (method) that will be executed by a job. Defining a task is as simple as annotating a method with the @Task method. Let's get started and define a task that says Hello world!.

package com.example.tasks;
import dev.doddle.core.engine.task.Task;

public class GreetingService {
    @Task()
    public void sayHello() {
        System.out.println("Hello world!");
    }
}

During the installation of Doddle you specify the basePackages path. This basePackages path is used to find classes that has methods annotated with the @Task annotation. If a method is found with this annotation then it is registered inside the TaskRegistry ready to be used by jobs.

In the example defined above, it is registered inside the TaskRegistry as sayHello

Options

You can change the name of a task and also add a description, such as:

@Task(name"hello", description="This tasks says hello")
public void sayHello() {
    System.out.println("Hello world!");
}

This task will be registered inside the registry as hello instead of sayHello.

Task names must be unique otherwise Doddle with throw an exception. If a task is found on one server and not the other then you will run into job processing issues!

Execution context

Arguments is data provided by a job when it is created. The task gets access to these arguments via the execution context.

Encrypted job arguments are decrypted when a job starts executing. Access them like you would any other value.

Arguments

The execution context has methods for retrieving an argument and also defining a default value for an argument if it does not exist.

Doddle will throw an exception if, for example, you try to fetch a string that has been stored as a number.

String

context.argument("name").asString();
// or how about an encrypted value?
context.argument("creditCardNumber").asString();

Or with a default value if the argument does not exist:

context.argument("name").asString("Jamie")

Numbers

Supported argument types for numbers are int, long and double.

context.argument("points").asInt();
context.argument("points").asLong();
context.argument("points").asDouble();

Or with a default value if the argument does not exist:

context.argument("points").asInt(20);
context.argument("points").asLong(20L);
context.argument("points").asDouble(0.5);

Boolean

context.argument("enabled").asBoolean();

Or with a default value if the argument does not exist:

context.argument("enabled").asBoolean(false)

Out of the box, doddle provides job logging to the storage provider with no configuration necessary.

The execution context provides methods to log information about the job. There are three logging levels supported: debug, info, and error. Debug is the default logging level.

Logging

Using the execution context passed into the task, let's log some messages!

context.logger().info("Hello world!");

Or using placeholders:

context.logger().info("Hello {}, you are {} years old", name, age);

An error message is not very useful without some context;

context.logger().error("Oh no, something happened", exception);

Configuration options

You can change the default logging level. For example, if you only want to log error messages to the storage.

During the configuration stage:

client.logger(options -> options.level(ERROR))

Progress

You can monitor the progress of your jobs using functionality provided by the execution context.

You can also track the progress of your job inside the Doddle Web Dashboard.

Here's an example:

@Task()
public void processOrders(ExecutionContext context) {
    final var progress = context.progress(100);
    for (int i = 0; i < 100; i++) {
        progress.advance();
    }
    // or advance by a specific value...
    progress.advance(50);
    // you can also log the current percentage...
    context.logger.info("Currently processed {}% of orders", progress.percentage());
}

Environment

During the configuration of Doddle, you can set environment values and these values are accessible to all jobs.

For example, let's say you set an environment value for the server called serverId.

To fetch this value you would do the following:

@Task()
public void processOrders(ExecutionContext context) {
    String serverId = (String) context.environment("serverId");
    context.logger.info("Job is executing on serverId: {}", serverId);
}

Last updated