Skip to main content

Tasks Overview

In this section, we delve into the specifics of the task executor's implementation.

A basic task implementation would appear as follows:

@CommandModel("example-task")
export class ExampleCommand extends TaskCommand {
@ApiProperty()
@IsString()
public name: string
}

@ResponseModel("example-task")
export class ExampleResponse extends TaskResult {
@ApiProperty()
@IsString()
public result: string
}

@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {

async processTask(exampleCommand: ExampleCommand): Promise<ExampleResponse> {
return {
result: `Hello ${exampleCommand.name} !!! `
}
}
}

decorator::@Executor

Marks the class as an executor of the task.

@Executor('example-task')
  • Parameters:
    • name: string - The name of the task
@Executor('example-1')
export class ExampleExecutor implements TaskExecutor {
async processTask(command: ExampleCommand): Promise<ExampleResponse> {
// shared implementation for all aliases
}
}

Task Status

A task can be in one of the following states:

ValueWhen
ACCEPTEDTask has been received and queued, but has not started running yet.
IN_PROGRESSTask is running. Appears on polled results between partial-result/progress emissions and the final response.
COMPLETEDTask finished successfully. The result field is populated.
FAILEDTask threw an error. The result field carries the ErrorResult (reason, message, statusCode, details).

interface::TaskExecutor

Tasks decorated as an executor should implement processTask method of TaskExecutor interface. Once a new task execution request is submitted the method will be called with the following params

  • command: Any - the input payload of the task passed in the request
  • meta: TaskMetadata - meta information about the task. The object can be used to identify the user, user's subscription plan and other info about request context.
@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {
async processTask(command: ExampleCommand, metadata: TaskMetadata, flow: Flow): Promise<ExampleResponse> {
const userId = flow.meta().userId();
return {
result: `Hello ${command.name}`
};
}
}
note

metadata: TaskMetadata is deprecated — prefer flow.meta() for new code. See the full surface, including the caller's subscription tier, in Flow Metadata.

@CommandModel("example-task")

Marks the class as input payload model for a given task

  • name: string - The name of the task

To apply validation on task input payload you can add decorators from class-validator on model properties

@CommandModel("example-task")
export class ExampleCommand extends TaskCommand {
@ApiProperty()
@IsString()
public name: string
}

@ResponseModel("example-task")

Marks the class as output payload model for a given task

  • name: string - The name of the task
@ResponseModel(Commands.EXAMPLE)
export class ExampleResponse extends TaskResult {
@ApiProperty()
@IsString()
public result: string
}
naming convention

To maintain consistency please keep naming convention of the classes.

  • Task Executor class name should end with Executor

  • Task input model name should end with Command

  • Task output model name should end with Response

  • Response result nested model (if any) name should end with Result