fn __schedule_list(value) {
if type_of(value) == "list" {
return value
}
return []
}
fn __schedule_string(value, fallback = "") {
if type_of(value) == "string" {
return value
}
return fallback
}
fn __schedule_int(value, fallback = nil) {
if type_of(value) == "int" {
return value
}
return fallback
}
fn __schedule_contains(values, value) {
return contains(__schedule_list(values), value)
}
fn __schedule_incoming_edges(graph, node_id) {
var incoming = []
for edge in __schedule_list(graph?.edges) {
if edge?.to == node_id {
incoming = incoming.push(edge)
}
}
return incoming
}
fn __schedule_required_inputs(node, incoming_count) {
let explicit = __schedule_int(node?.join_policy?.min_completed)
if explicit != nil {
return explicit
}
let strategy = __schedule_string(node?.join_policy?.strategy, "all")
if node?.join_policy?.require_all_inputs || strategy == "all" {
return incoming_count
}
return 1
}
/** workflow_join_readiness. */
pub fn workflow_join_readiness(config = nil) {
let node_id = __schedule_string(config?.node_id, "")
let node = config?.node ?? {}
let graph = config?.graph ?? {}
let completed_nodes = __schedule_list(config?.completed_nodes)
let incoming = __schedule_incoming_edges(graph, node_id)
let required = __schedule_required_inputs(node, len(incoming))
var completed_inputs = 0
for edge in incoming {
if __schedule_contains(completed_nodes, edge?.from) {
completed_inputs = completed_inputs + 1
}
}
return {ready: completed_inputs >= required, required: required, completed_inputs: completed_inputs}
}
fn __schedule_branch_matches(left, right) {
if left == nil && right == nil {
return true
}
return left == right
}
/** workflow_next_edges. */
pub fn workflow_next_edges(config = nil) {
let graph = config?.graph ?? {}
let current = __schedule_string(config?.current, "")
let branch = config?.branch
var exact = []
var default_edges = []
for edge in __schedule_list(graph?.edges) {
if edge?.from != current {
continue
}
if __schedule_branch_matches(edge?.branch, branch) {
exact = exact.push(edge)
}
if edge?.branch == nil {
default_edges = default_edges.push(edge)
}
}
if len(exact) > 0 || branch == nil {
return exact
}
return default_edges
}