pub type WorkflowJoinPolicy = {strategy?: string, min_completed?: int?, require_all_inputs?: bool}
pub type WorkflowScheduleEdge = {from: string, to: string, branch?: string?, label?: string?}
type WorkflowScheduleGraph = {edges?: list<WorkflowScheduleEdge>, ...dict}
type WorkflowJoinConfig = {
node_id?: string,
node?: {join_policy?: WorkflowJoinPolicy, ...dict},
graph?: WorkflowScheduleGraph,
completed_nodes?: list<string>,
}
pub type WorkflowJoinReadiness = {ready: bool, required: int, completed_inputs: int}
type WorkflowNextEdgesConfig = {graph?: WorkflowScheduleGraph, current?: string, branch?: string?}
fn __schedule_incoming_edges(
graph: WorkflowScheduleGraph,
node_id: string,
) -> list<WorkflowScheduleEdge> {
let incoming: list<WorkflowScheduleEdge> = []
for edge in graph.edges ?? [] {
if edge.to == node_id {
incoming.push(edge)
}
}
return incoming
}
fn __schedule_required_inputs(policy: WorkflowJoinPolicy, incoming_count: int) -> int {
if policy.min_completed != nil {
return policy.min_completed
}
if (policy.require_all_inputs ?? false) || (policy.strategy ?? "all") == "all" {
return incoming_count
}
return 1
}
/**
* workflow_join_readiness.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn workflow_join_readiness(config: WorkflowJoinConfig? = nil) -> WorkflowJoinReadiness {
const options = config ?? {}
const node = options.node ?? {}
const graph = options.graph ?? {}
const completed_nodes = options.completed_nodes ?? []
const incoming = __schedule_incoming_edges(graph, options.node_id ?? "")
const required = __schedule_required_inputs(node.join_policy ?? {}, len(incoming))
let completed_inputs = 0
for edge in incoming {
if contains(completed_nodes, edge.from) {
completed_inputs = completed_inputs + 1
}
}
return {
ready: completed_inputs >= required,
required: required,
completed_inputs: completed_inputs,
}
}
/**
* workflow_next_edges.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn workflow_next_edges(config: WorkflowNextEdgesConfig? = nil) -> list<WorkflowScheduleEdge> {
const options = config ?? {}
const graph = options.graph ?? {}
const current = options.current ?? ""
const branch = options.branch
let exact: list<WorkflowScheduleEdge> = []
let default_edges: list<WorkflowScheduleEdge> = []
for edge in graph.edges ?? [] {
if edge.from != current {
continue
}
if edge.branch == branch {
exact.push(edge)
}
if edge.branch == nil {
default_edges.push(edge)
}
}
if len(exact) > 0 || branch == nil {
return exact
}
return default_edges
}