Skip to content

Async Tasks

By default, each task in a workflow is synchronous and executes in real time until completion. However, there may be tasks that require longer running time or wait on an external event before completion. For such cases, you can designate a task as async.

Lifecycle

An async task will finish it's code execution and wait for a callback. The task's status is set to awaiting until an external callback request is made to signify the completion of this task. Alternatively, the callback can fail the task.

graph LR classDef default fill:#FFFFFF; classDef red fill:#FF8A8A; classDef green fill:#8AFF8A; subgraph "Asynchronous Task" A2(Pending) -->|scheduled| B2(Active) -->|runs|C2(Awaiting) B2 -->|fails| D2(Failed) C2 -..- E2 subgraph While Awaiting E2[External Server] --> |HTTPS callback| D2 E2 --> |HTTPS callback| F2(Complete) end style E2 fill:#f9f class F2 green; class D2 red; end subgraph "Synchronous Task (default)" A1(Pending) -->|scheduled| B1(Active) -->|runs|C1(Complete) B1 -->|fails| D1(Failed) class C1 green; class D1 red; end

Callback Request Specifications

To continue the execution of a workflow with an async task, make a POST request to https://api.vibeiq.com/prod/api/external-events/callback/ with a JSON payload containing the following properties:

  • taskId (string): The ID of the async task to be called back
  • logs (string | array): The logs to be appended to the task logs. If this is a string, it will be treated as one line. If this is an array of strings, each entry will be its own line. All log lines will be prepended with a timestamp of when the server received the callback.
  • status (string): FAILURE or SUCCESS, depending on what you wish the task's status to be. A failed task will cause the workflow run to fail, and no futher tasks will be ran.
  • output (object): An object of additional output you wish to merge with the task's existing output. Callback output will be prioritized over the task's native output.
  • subtext (string): A string to specify the task and process subtext.

Sample payload:

const axios = require('axios')
const response = axios.post(
    'https://api.vibeiq.com/prod/api/external-events/callback/',
    {
        "taskId": "12345678",
        "logs": "line one\nline two", // or ["line one", "line two"]
        "status": "SUCCESS",
        "output": {
            "zipFileLocation": "https://example.com/jpeg"
        },
        "subtext": "Completed with 90/100 passing"
    },
    {
        headers: {
            {
                "Content-Type": "application/json",
                "Authorization": "bearer AUTH_TOKEN"
            }
    }
)

Task Subtext

Each task contains a subtext field that can be updated to reflect the latest state of the job. This is especially relevant to long running async tasks. Subtext helps you check on your task's status at a glance. When you update a task's subtext, it also updates its parent process's subtext. Subtext can be modified on an asynchronous callback request. Additionally, subtext is not limited to async tasks, and can be added to any task.

Task Subtext Example

Task subtext eample

curl --request PUT \
    --url https://api.vibeiq.com/prod/api/event-workflow-tasks/my-task-id \
    --header 'Content-Type: application/json' \
    --header 'X-Api-Key: API_KEY' \
    --header 'X-Api-Org: ORG_KEY' \
    --data '{
        "subtext": "Completed with 90/100 passing"
    }'
import {Entities} from "@contrail/sdk";
await new Entities().update({
        entityName: 'event-workflow-task',
        'my-task-id',
        {
            subtext: 'Completed with 90/100 passing'
        }
    });
import com.vibeiq.sdk.entities.EntitiesClientUpdateOptions;
import com.vibeiq.sdk.entities.Entities;
import org.json.JSONObject;
import com.vibeiq.sdk.core.request.ApiKeyRequestModule;
JSONObject payload = new JSONObject();
payload.put("subtext", "subtext- string");
EntitiesClientUpdateOptions options =
    new EntitiesClientUpdateOptions("event-workflow-task",
    "my-task-id", payload.toString(), "", "");
Entities e = new Entities(new ApiKeyRequestModule());
JSONObject res = e.update(options);