Skip to main content

TaskAction Resource Definition

The TaskAction Custom Resource Definition (CRD) is the primary mechanism Flyte uses to execute and track individual tasks within a workflow. It acts as a bridge between the Flyte control plane (which decides what needs to run) and the execution engine (which manages the actual Kubernetes resources or external service calls).

Defining the Task with TaskActionSpec

When Flyte needs to execute a task, it creates a TaskAction resource. The TaskActionSpec (defined in executor/api/v1/taskaction_types.go) contains all the information required to identify the task, provide its inputs, and determine which plugin should handle the execution.

You define a task execution by populating the Spec with identifiers and execution context:

taskAction := &executorv1.TaskAction{
ObjectMeta: metav1.ObjectMeta{
Name: "my-run-a0", // Generated name
Namespace: "flyte-tasks",
Labels: map[string]string{
"flyte.org/project": "my-project",
"flyte.org/domain": "production",
"flyte.org/run": "my-run",
"flyte.org/action": "task1",
},
},
Spec: executorv1.TaskActionSpec{
Project: "my-project",
Domain: "production",
RunName: "my-run",
ActionName: "task1",
TaskType: "container",
InputURI: "s3://my-bucket/inputs.pb",
RunOutputBase: "s3://my-bucket/outputs/",
TaskTemplate: serializedTemplate, // Proto-serialized core.TaskTemplate
},
}

Key Specification Fields

  • TaskType: This string (e.g., "container", "spark", "ray") is used by the TaskActionController to look up the appropriate plugin to handle the task.
  • TaskTemplate: A []byte field containing the proto-serialized core.TaskTemplate. This contains the actual command, image, and resource requirements for the task.
  • InputURI and RunOutputBase: These define where the task should read its input data and where it is expected to write its results.
  • CacheKey: If set, the executor will attempt to look up previous results in the Flyte Catalog before executing the task.

Tracking Execution with TaskActionStatus

The TaskActionStatus tracks the observed state of the task as it moves through its lifecycle. Unlike standard Kubernetes resources that might only use conditions, TaskAction maintains detailed plugin state and a full history of transitions.

Plugin State and Phases

The PluginPhase field provides a human-readable string of the current execution stage (e.g., "Queued", "Running", "Succeeded"). Internally, the PluginState field stores Gob-encoded data that allows plugins to resume their work across reconciliation loops without losing context.

Phase History and Conditions

Flyte uses two complementary ways to track progress in executor/api/v1/taskaction_types.go:

  1. Conditions: A Kubernetes-native list of metav1.Condition objects. The TaskActionController updates these in-place. Common types include Progressing, Succeeded, and Failed.
  2. PhaseHistory: An append-only log of PhaseTransition objects. This preserves the timeline of every state change, including timestamps and optional messages.
type PhaseTransition struct {
Phase string `json:"phase"`
OccurredAt metav1.Time `json:"occurredAt"`
Message string `json:"message,omitempty"`
}

Handling Failures

Flyte distinguishes between user-level task failures and system-level infrastructure errors:

  • SystemFailures: This counter tracks transient errors (like Kubernetes API timeouts or admission webhook denials). If SystemFailures exceeds the configured maximum (defaulting to 3), the TaskAction is transitioned to a permanent failure.
  • ErrorState: When a task fails, the ErrorState struct captures the structured error returned by the plugin. This includes a Code (e.g., "OOMKilled"), a Kind (USER or SYSTEM), and a human-readable Message.

Resource Lifecycle

The lifecycle of a TaskAction is managed by several components within the Flyte executor:

  1. Creation: The Actions service (actions/k8s/client.go) instantiates the TaskAction CR. It sets up labels and owner references to ensure that if a parent run is deleted, the child tasks are cleaned up automatically.
  2. Reconciliation: The TaskActionController (executor/pkg/controller/taskaction_controller.go) watches for these resources. It identifies the correct plugin based on Spec.TaskType, calls the plugin's Handle method, and updates the Status based on the result.
  3. Finalization: Flyte attaches a finalizer (flyte.org/plugin-finalizer) to the resource. This ensures that even if the CR is deleted, the plugin has a chance to perform cleanup (like killing a remote Spark job or deleting a pod) before the Kubernetes resource is fully removed.
  4. Garbage Collection: Once a task reaches a terminal state (Succeeded or Failed), the GarbageCollector (executor/pkg/controller/garbage_collector.go) monitors it. After a grace period, it deletes the terminal TaskAction to prevent etcd bloat.