a9cd7750f4
CI / detect-changes (push) Waiting to run
CI / build (push) Waiting to run
UI v2 CI / E2E (Mocked) (push) Blocked by required conditions
UI v2 Integration CI / E2E (Integration) (push) Waiting to run
CI / unit-test (push) Blocked by required conditions
CI / test-harness (push) Waiting to run
CI / generate-e2e-matrix (push) Waiting to run
CI / e2e (push) Blocked by required conditions
CI / build-ui (push) Waiting to run
Publish docs via GitHub Pages / Deploy docs (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
UI v2 CI / Lint, Format & Test (push) Waiting to run
184 lines
6.8 KiB
Markdown
184 lines
6.8 KiB
Markdown
---
|
|
description: "Understand the task lifecycle in Conductor — state transitions, retries, timeouts, and failure handling for durable workflow execution."
|
|
---
|
|
|
|
# Task Lifecycle
|
|
|
|
During a workflow execution, each task transitions through a series of states. Understanding these transitions is key to configuring retries, timeouts, and error handling correctly.
|
|
|
|
## State diagram
|
|
|
|
```mermaid
|
|
stateDiagram-v2
|
|
[*] --> SCHEDULED
|
|
SCHEDULED --> IN_PROGRESS : Worker polls task
|
|
SCHEDULED --> TIMED_OUT : Poll timeout exceeded
|
|
SCHEDULED --> CANCELED : Workflow terminated
|
|
IN_PROGRESS --> COMPLETED : Worker reports success
|
|
IN_PROGRESS --> FAILED : Worker reports failure
|
|
IN_PROGRESS --> FAILED_WITH_TERMINAL_ERROR : Non-retryable failure
|
|
IN_PROGRESS --> TIMED_OUT : Response/task timeout exceeded
|
|
IN_PROGRESS --> COMPLETED_WITH_ERRORS : Optional task fails
|
|
SCHEDULED --> SKIPPED : Skip Task API called
|
|
FAILED --> SCHEDULED : Retry (after delay)
|
|
TIMED_OUT --> SCHEDULED : Retry (after delay)
|
|
COMPLETED --> [*]
|
|
FAILED --> [*] : Retries exhausted or totalTimeoutSeconds exceeded
|
|
FAILED_WITH_TERMINAL_ERROR --> [*]
|
|
TIMED_OUT --> [*] : Retries exhausted or totalTimeoutSeconds exceeded
|
|
CANCELED --> [*]
|
|
SKIPPED --> [*]
|
|
COMPLETED_WITH_ERRORS --> [*]
|
|
```
|
|
|
|
## Task statuses
|
|
|
|
| Status | Description |
|
|
| :--- | :--- |
|
|
| `SCHEDULED` | Task is queued and waiting for a worker to poll it. |
|
|
| `IN_PROGRESS` | A worker has picked up the task and is executing it. |
|
|
| `COMPLETED` | Task completed successfully. |
|
|
| `FAILED` | Task failed due to an error. Conductor will retry based on the task definition's retry configuration. |
|
|
| `FAILED_WITH_TERMINAL_ERROR` | Task failed with a non-retryable error. No retries will be attempted. |
|
|
| `TIMED_OUT` | Task exceeded its configured timeout. Conductor will retry based on the retry configuration. |
|
|
| `CANCELED` | Task was canceled because the workflow was terminated. |
|
|
| `SKIPPED` | Task was skipped via the Skip Task API. The workflow continues to the next task. |
|
|
| `COMPLETED_WITH_ERRORS` | Task failed but is marked as optional in the workflow definition. The workflow continues. |
|
|
|
|
|
|
## Retry behavior
|
|
|
|
When a task fails with a retryable error, Conductor automatically reschedules it after the configured delay.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant W as Worker
|
|
participant C as Conductor Server
|
|
|
|
C->>W: Task T1 available for polling
|
|
W->>C: Poll task T1
|
|
C-->>W: Return T1 (IN_PROGRESS)
|
|
W->>W: Process task...
|
|
W->>C: Report FAILED (after 10s)
|
|
C->>C: Persist failed execution
|
|
Note over C: Wait retryDelaySeconds (5s)
|
|
C->>C: Schedule new T1 execution
|
|
C->>W: T1 available for polling again
|
|
W->>C: Poll task T1
|
|
C-->>W: Return T1 (IN_PROGRESS)
|
|
W->>W: Process task...
|
|
W->>C: Report COMPLETED
|
|
```
|
|
|
|
Retry behavior is controlled by the task definition:
|
|
|
|
| Parameter | Description |
|
|
| :--- | :--- |
|
|
| `retryCount` | Maximum number of retry attempts. |
|
|
| `retryLogic` | `FIXED`, `EXPONENTIAL_BACKOFF`, or `LINEAR_BACKOFF`. See [Retry Logic](../../../documentation/configuration/taskdef.md#retry-logic). |
|
|
| `retryDelaySeconds` | Base delay between retries. |
|
|
| `maxRetryDelaySeconds` | Caps the computed delay. Prevents exponential growth from becoming arbitrarily large. |
|
|
| `backoffJitterMs` | Adds random milliseconds to each delay to spread concurrent retries over time. |
|
|
| `totalTimeoutSeconds` | Hard wall-clock budget across all attempts. See [Total timeout](#total-timeout). |
|
|
|
|
|
|
## Timeout scenarios
|
|
|
|
### Poll timeout
|
|
|
|
If no worker polls the task within `pollTimeoutSeconds`, it is marked as `TIMED_OUT`.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant W as Worker
|
|
participant C as Conductor Server
|
|
|
|
C->>C: Schedule task T1
|
|
Note over C,W: No worker polls within 60s
|
|
C->>C: Mark T1 as TIMED_OUT
|
|
C->>C: Schedule retry (if retries remain)
|
|
```
|
|
|
|
This typically indicates a backlogged task queue or insufficient workers.
|
|
|
|
### Response timeout
|
|
|
|
If a worker polls a task but doesn't report back within `responseTimeoutSeconds`, the task is marked as `TIMED_OUT`. This handles cases where a worker crashes mid-execution.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant W as Worker
|
|
participant C as Conductor Server
|
|
|
|
C->>W: Task T1 available
|
|
W->>C: Poll T1
|
|
C-->>W: Return T1 (IN_PROGRESS)
|
|
W->>W: Processing...
|
|
Note over W: Worker crashes
|
|
Note over C: responseTimeoutSeconds (20s) elapsed
|
|
C->>C: Mark T1 as TIMED_OUT
|
|
Note over C: Wait retryDelaySeconds (5s)
|
|
C->>C: Schedule new T1 execution
|
|
```
|
|
|
|
Workers can extend the response timeout by sending `IN_PROGRESS` status updates with a `callbackAfterSeconds` value.
|
|
|
|
### Task timeout
|
|
|
|
`timeoutSeconds` is the overall SLA for task completion. Even if a worker keeps sending `IN_PROGRESS` updates, the task is marked as `TIMED_OUT` once this duration is exceeded.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant W as Worker
|
|
participant C as Conductor Server
|
|
|
|
C->>W: Task T1 available
|
|
W->>C: Poll T1
|
|
C-->>W: Return T1 (IN_PROGRESS)
|
|
W->>W: Processing...
|
|
W->>C: IN_PROGRESS (callback: 9s)
|
|
Note over C: Task back in queue, invisible 9s
|
|
W->>C: Poll T1 again
|
|
W->>C: IN_PROGRESS (callback: 9s)
|
|
Note over C: Cycle repeats...
|
|
Note over C: timeoutSeconds (30s) elapsed
|
|
C->>C: Mark T1 as TIMED_OUT
|
|
C->>C: Schedule retry (if retries remain)
|
|
W->>C: Report COMPLETED (at 32s)
|
|
Note over C: Ignored — T1 already terminal
|
|
```
|
|
|
|
### Total timeout
|
|
|
|
`totalTimeoutSeconds` limits the total wall-clock time across **all** retry attempts. Once this budget is consumed, no further retries are scheduled regardless of how many remain in `retryCount`.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant W as Worker
|
|
participant C as Conductor Server
|
|
|
|
Note over C: totalTimeoutSeconds = 30s
|
|
C->>W: Task T1 (attempt 1)
|
|
W->>C: FAILED (at t=5s)
|
|
Note over C: Retry delay 5s
|
|
C->>W: Task T1 (attempt 2, at t=10s)
|
|
W->>C: FAILED (at t=20s)
|
|
Note over C: Retry delay 5s
|
|
C->>W: Task T1 (attempt 3, at t=25s)
|
|
W->>C: FAILED (at t=28s)
|
|
Note over C: t=28s ≥ 30s → total budget exhausted
|
|
C->>C: Mark workflow FAILED — no more retries
|
|
```
|
|
|
|
This is useful when you need a hard SLA on how long a task can run across all its attempts, independent of how many retries are configured.
|
|
|
|
## Timeout configuration summary
|
|
|
|
| Parameter | Description | Default |
|
|
| :--- | :--- | :--- |
|
|
| `pollTimeoutSeconds` | Max time for a worker to poll the task. | No timeout |
|
|
| `responseTimeoutSeconds` | Max time for a worker to respond after polling. | 600s |
|
|
| `timeoutSeconds` | SLA per individual attempt (from first `IN_PROGRESS` to terminal). | No timeout |
|
|
| `totalTimeoutSeconds` | Hard budget across all attempts combined. Overrides `retryCount`. | No timeout |
|
|
| `timeoutPolicy` | Action on timeout: `RETRY`, `TIME_OUT_WF` (fail workflow), or `ALERT_ONLY`. | `TIME_OUT_WF` |
|