[wip] workflow cancellation policy
Some checks failed
CI / Rustfmt (push) Successful in 21s
CI / Cargo Audit & Deny (push) Successful in 32s
CI / Web Blocking Checks (push) Successful in 50s
CI / Security Blocking Checks (push) Successful in 9s
CI / Clippy (push) Failing after 1m58s
CI / Web Advisory Checks (push) Successful in 34s
CI / Security Advisory Checks (push) Successful in 1m26s
CI / Tests (push) Successful in 8m47s
Some checks failed
CI / Rustfmt (push) Successful in 21s
CI / Cargo Audit & Deny (push) Successful in 32s
CI / Web Blocking Checks (push) Successful in 50s
CI / Security Blocking Checks (push) Successful in 9s
CI / Clippy (push) Failing after 1m58s
CI / Web Advisory Checks (push) Successful in 34s
CI / Security Advisory Checks (push) Successful in 1m26s
CI / Tests (push) Successful in 8m47s
This commit is contained in:
@@ -40,6 +40,7 @@ import type {
|
||||
WorkflowBuilderState,
|
||||
PaletteAction,
|
||||
TransitionPreset,
|
||||
CancellationPolicy,
|
||||
} from "@/types/workflow";
|
||||
import {
|
||||
generateUniqueTaskName,
|
||||
@@ -53,6 +54,7 @@ import {
|
||||
removeTaskFromTransitions,
|
||||
renameTaskInTransitions,
|
||||
findStartingTaskIds,
|
||||
CANCELLATION_POLICY_LABELS,
|
||||
} from "@/types/workflow";
|
||||
|
||||
const INITIAL_STATE: WorkflowBuilderState = {
|
||||
@@ -67,6 +69,7 @@ const INITIAL_STATE: WorkflowBuilderState = {
|
||||
tasks: [],
|
||||
tags: [],
|
||||
enabled: true,
|
||||
cancellationPolicy: "allow_finish",
|
||||
};
|
||||
|
||||
export default function WorkflowBuilderPage() {
|
||||
@@ -135,6 +138,7 @@ export default function WorkflowBuilderPage() {
|
||||
const name =
|
||||
refParts.length > 1 ? refParts.slice(1).join(".") : workflow.ref;
|
||||
|
||||
const defn = workflow.definition as Record<string, unknown> | undefined;
|
||||
const builderState = definitionToBuilderState(
|
||||
{
|
||||
ref: workflow.ref,
|
||||
@@ -143,10 +147,15 @@ export default function WorkflowBuilderPage() {
|
||||
version: workflow.version,
|
||||
parameters: workflow.param_schema || undefined,
|
||||
output: workflow.out_schema || undefined,
|
||||
tasks:
|
||||
((workflow.definition as Record<string, unknown>)
|
||||
?.tasks as WorkflowYamlDefinition["tasks"]) || [],
|
||||
vars: (defn?.vars as Record<string, unknown>) || undefined,
|
||||
tasks: (defn?.tasks as WorkflowYamlDefinition["tasks"]) || [],
|
||||
output_map: (defn?.output_map as Record<string, string>) || undefined,
|
||||
tags: workflow.tags,
|
||||
cancellation_policy:
|
||||
(defn?.cancellation_policy as
|
||||
| "allow_finish"
|
||||
| "cancel_running"
|
||||
| undefined) || undefined,
|
||||
},
|
||||
workflow.pack_ref,
|
||||
name,
|
||||
@@ -843,6 +852,24 @@ export default function WorkflowBuilderPage() {
|
||||
/>
|
||||
Enabled
|
||||
</label>
|
||||
<select
|
||||
value={state.cancellationPolicy}
|
||||
onChange={(e) =>
|
||||
updateMetadata({
|
||||
cancellationPolicy: e.target.value as CancellationPolicy,
|
||||
})
|
||||
}
|
||||
className="px-2 py-1 border border-gray-200 rounded text-xs text-gray-600 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 bg-white"
|
||||
title="Cancellation policy: controls how running tasks behave when the workflow is cancelled"
|
||||
>
|
||||
{Object.entries(CANCELLATION_POLICY_LABELS).map(
|
||||
([value, label]) => (
|
||||
<option key={value} value={value}>
|
||||
{label}
|
||||
</option>
|
||||
),
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -185,6 +185,23 @@ export interface WorkflowEdge {
|
||||
labelPosition?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancellation policy for a workflow.
|
||||
*
|
||||
* Controls what happens to running tasks when a workflow is cancelled:
|
||||
* - `allow_finish` (default): Running tasks complete naturally; only
|
||||
* pending/requested tasks are cancelled and no new tasks are dispatched.
|
||||
* - `cancel_running`: All running and pending tasks are forcefully cancelled.
|
||||
* Running processes receive SIGINT → SIGTERM → SIGKILL via the worker.
|
||||
*/
|
||||
export type CancellationPolicy = "allow_finish" | "cancel_running";
|
||||
|
||||
/** Human-readable labels for each cancellation policy */
|
||||
export const CANCELLATION_POLICY_LABELS: Record<CancellationPolicy, string> = {
|
||||
allow_finish: "Allow running tasks to finish",
|
||||
cancel_running: "Cancel running tasks",
|
||||
};
|
||||
|
||||
/** Complete workflow builder state */
|
||||
export interface WorkflowBuilderState {
|
||||
/** Workflow name (used to derive ref and filename) */
|
||||
@@ -209,6 +226,8 @@ export interface WorkflowBuilderState {
|
||||
tags: string[];
|
||||
/** Whether the workflow is enabled */
|
||||
enabled: boolean;
|
||||
/** Cancellation policy (default: allow_finish) */
|
||||
cancellationPolicy: CancellationPolicy;
|
||||
}
|
||||
|
||||
/** Parameter definition in flat schema format */
|
||||
@@ -238,6 +257,7 @@ export interface WorkflowYamlDefinition {
|
||||
tasks: WorkflowYamlTask[];
|
||||
output_map?: Record<string, string>;
|
||||
tags?: string[];
|
||||
cancellation_policy?: CancellationPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,6 +272,7 @@ export interface WorkflowGraphDefinition {
|
||||
vars?: Record<string, unknown>;
|
||||
tasks: WorkflowYamlTask[];
|
||||
output_map?: Record<string, string>;
|
||||
cancellation_policy?: CancellationPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,6 +471,10 @@ export function builderStateToDefinition(
|
||||
definition.tags = state.tags;
|
||||
}
|
||||
|
||||
if (state.cancellationPolicy !== "allow_finish") {
|
||||
definition.cancellation_policy = state.cancellationPolicy;
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
@@ -537,6 +562,10 @@ export function builderStateToGraph(
|
||||
graph.vars = state.vars;
|
||||
}
|
||||
|
||||
if (state.cancellationPolicy !== "allow_finish") {
|
||||
graph.cancellation_policy = state.cancellationPolicy;
|
||||
}
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
@@ -723,6 +752,7 @@ export function definitionToBuilderState(
|
||||
tasks,
|
||||
tags: definition.tags || [],
|
||||
enabled: true,
|
||||
cancellationPolicy: definition.cancellation_policy || "allow_finish",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user