Managing Tasks

Infinitic is still in active development. Subscribe here to follow the progress.

Infinitic client lets us start and cancel tasks, usually from your Web App controllers.

Starting New Tasks

New task stub

The Infinitic client manages tasks through stubs built from the task interface. Here is an example of task interface from our Hello World app:

public interface HelloWorldService {
    String sayHello(String name);

    String addEnthusiasm(String str);
}
interface HelloWorldService {
    fun sayHello(name: String?): String

    fun addEnthusiasm(str: String): String
}

Using this interface, an Infinitic client can create a stub that behaves syntactically as a new instance of this task:

HelloWorldService helloWorldService = client.newTask(HelloWorldService.class);
val helloWorldService = client.newTask<HelloWorldService>()

We can also add tags to this instance. It can be very useful to target later this instance by tag:

Set<String> tags = new HashSet<>();
tags.add("foo");
tags.add("bar");

HelloWorldService helloWorldService = client.newTask(HelloWorldService.class, tags);
val helloWorldService = client.newTask<HelloWorldService>(tags = setOf("foo", "bar"))

Synchronous start

This stub can be used to trigger a synchronous execution:

String hello = helloWorldService.sayHello("Infinitic");
val hello = helloWorldService.sayHello("Infinitic")

When dispatching a task, the client serializes parameters and send them through Pulsar to the task engine, that will make sure the task is processed, managing retries if needed. Eventually, the return value will be serialized and sent back to the client through Pulsar:

Asynchronous start

Of course, we can also trigger an asynchronous execution:

Deferred<String> deferred = client.async(helloWorldService, t -> t.sayHello("Infinitic"));
val deferred = client.async(helloWorldService) { sayHello("Infinitic") }

We can use the returned Deferred<T> to:

  • wait for the synchronous completion:

    T result = deferred.await();
    
    val result: T = deferred.await()
    

    where T is the actual return type.

    The await() method blocks the current thread of the client - up to the task termination. It will throw an UnknownTask exception if the task is already terminated.

  • retrieve the underlying task's id:

    java.util.UUID id = deferred.id;
    
    val id: java.util.UUID = deferred.id
    

Managing Running Tasks

A task is said running, as long as it is neither completed neither canceled.

Running task stub

We can create the stub of a running task from its id:

HelloWorldService helloWorldService = client.getTask(HelloWorldService.class, id);
val helloWorldService = client.getTask<HelloWorldService>(id)

Alternatively, we can create a stub targeting all running tasks having a tag "foo":

HelloWorldService helloWorldService = client.getTask(HelloWorldService.class, "foo");
val helloWorldService = client.getTask<HelloWorldService>(tag = "foo")

Retry a running task

Using this stub, we can force the retry of this task:

client.retry(carRentalService);
client.retry(carRentalService)

Cancel a running task

Or cancel this task:

client.cancel(carRentalService);
client.cancel(carRentalService)

@Name annotation

A task instance is internally described by both its full java name (including its package) and the name of the method called.

In some situations we may want to avoid coupling those names with the underlying implementation, for example if we want to rename the class or method, or if we mix programming languages.

Infinitic provides a @Name annotation that let us declare explicitly the names that Infinitic should use internally. For example:

package hello.world.tasks;

import io.infinitic.annotations.Name;

@Name("HelloService")
public interface HelloWorldService {
    @Name("sayHelloTask")
    String sayHello(String name);

    @Name("addEnthusiasmTask")
    String addEnthusiasm(String str);
}
package hello.world.tasks

import io.infinitic.annotations.Name

@Name('HelloService')
interface HelloWorldService {

    @Name('sayHelloTask')
    fun sayHello(name: String?): String

    @Name('addEnthusiasmTask')
    fun addEnthusiasm(str: String): String
}

When using this annotation, the name setting in task worker configuration file should be the one provided by the annotation:

tasks:
  - name: HelloService
    class: hello.world.tasks.HelloWorldServiceImpl
Edit this page on GitHub Updated at Fri, May 28, 2021