Skip to main content

Workflow Progress

During workflow execution, you can provide real-time progress information to the client application. The framework supports three distinct types of progress updates to keep clients informed about the task execution status:

Progress Metrics

Currently available via Async API

Progress metrics allow you to report completion percentage and estimated remaining time for a task. This is particularly useful for long-running operations where clients need to track overall progress.


@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {
async processTask(command: any, metadata: TaskMetadata, flow: Flow): Promise<ExampleResponse> {
await flow.emitProgresMetrics({
percent: 27, // progress percentage (0 to 100)
estimatedSecondsLeft: 14, // optional remaining time in seconds
});
sleep(5000);
return {
name: 'Joe',
surname: `Doe`
}
}
}

For tasks with predictable durations, you can automatically schedule progress updates based on the average execution time:


@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {
async processTask(command: any, metadata: TaskMetadata, flow: Flow): Promise<ExampleResponse> {
await flow.scheduleProgressMetrics(60_000);
sleep(5000);
return {
name: 'Joe',
surname: `Doe`
}
}
}

Partial Result

Currently available via Async API

Partial results enable you to send intermediate results to the client during task execution. These results should be a subset of your final result schema, allowing clients to start processing data before the task completes.

Important: Only the most recently emitted partial result is accessible to clients during polling.


@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {
async processTask(command: any, metadata: TaskMetadata, flow: Flow): Promise<ExampleResponse> {
await flow.emitPartialResult({
name: 'Joe'
});
sleep(5000);
return {
name: 'Joe',
surname: `Doe`
}
}
}

Events

Available via Stream API and Async API

Events provide a way to send structured updates about specific occurrences during workflow execution. Unlike partial results, events are accumulated and can be used to communicate various execution milestones or state changes.

  • Stream API: Events are streamed to the client in real-time as they are emitted.
  • Async API: Events are stored and returned as part of the events array when polling the task result. The framework assigns a unique id to each event for deduplication across polls.
note

Async API support for events requires @picsart/pa-pluggable-workers-core version 6.15.0 or higher.

When using the workflows client, events can be consumed via the onEvent callback passed to workflows.run() in both Stream and Async modes. In Async mode, the client uses the ids to deduplicate events across polls; without the client, you must track seen ids yourself.

Always await emitEvent

flow.emitEvent() returns a Promise. You must await each call to guarantee that events are delivered in order and that all events are included in the final result.


@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {
async processTask(command: any, metadata: TaskMetadata, flow: Flow): Promise<ExampleResponse> {
await flow.emitEvent({
type: 'name.generated',
data: {
name: 'Joe'
}
});
sleep(5000);
await flow.emitEvent({
type: 'surname.generated',
data: {
surname: 'Doe'
}
});
return {
name: 'Joe',
surname: `Doe`
}
}
}