Skip to content

Commit 298546d

Browse files
fix(parallel): add parallel sentinel to make parallel-parallel and parallel-loop work correctly (#2593)
* fix(parallel): add parallel sentinel to make parallel-parallel and parallel-loop work correctly * fix regular -> parallel + copilot nested subflows * add tests * consolidate to always explode parallel dag at runtime
1 parent b60b98e commit 298546d

File tree

13 files changed

+1200
-643
lines changed

13 files changed

+1200
-643
lines changed

apps/sim/executor/constants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const EDGE = {
5353
LOOP_CONTINUE: 'loop_continue',
5454
LOOP_CONTINUE_ALT: 'loop-continue-source',
5555
LOOP_EXIT: 'loop_exit',
56+
PARALLEL_EXIT: 'parallel_exit',
5657
ERROR: 'error',
5758
SOURCE: 'source',
5859
DEFAULT: 'default',
@@ -88,6 +89,16 @@ export const PARALLEL = {
8889
SUFFIX: '₎',
8990
},
9091

92+
SENTINEL: {
93+
PREFIX: 'parallel-',
94+
START_SUFFIX: '-sentinel-start',
95+
END_SUFFIX: '-sentinel-end',
96+
START_TYPE: 'start' as SentinelType,
97+
END_TYPE: 'end' as SentinelType,
98+
START_NAME_PREFIX: 'Parallel Start',
99+
END_NAME_PREFIX: 'Parallel End',
100+
},
101+
91102
DEFAULT_COUNT: 1,
92103
} as const
93104

apps/sim/executor/dag/builder.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ import { createLogger } from '@sim/logger'
22
import { EdgeConstructor } from '@/executor/dag/construction/edges'
33
import { LoopConstructor } from '@/executor/dag/construction/loops'
44
import { NodeConstructor } from '@/executor/dag/construction/nodes'
5+
import { ParallelConstructor } from '@/executor/dag/construction/parallels'
56
import { PathConstructor } from '@/executor/dag/construction/paths'
67
import type { DAGEdge, NodeMetadata } from '@/executor/dag/types'
7-
import { buildSentinelStartId, extractBaseBlockId } from '@/executor/utils/subflow-utils'
8+
import {
9+
buildParallelSentinelStartId,
10+
buildSentinelStartId,
11+
extractBaseBlockId,
12+
} from '@/executor/utils/subflow-utils'
813
import type {
914
SerializedBlock,
1015
SerializedLoop,
@@ -31,6 +36,7 @@ export interface DAG {
3136
export class DAGBuilder {
3237
private pathConstructor = new PathConstructor()
3338
private loopConstructor = new LoopConstructor()
39+
private parallelConstructor = new ParallelConstructor()
3440
private nodeConstructor = new NodeConstructor()
3541
private edgeConstructor = new EdgeConstructor()
3642

@@ -50,6 +56,7 @@ export class DAGBuilder {
5056
const reachableBlocks = this.pathConstructor.execute(workflow, triggerBlockId)
5157

5258
this.loopConstructor.execute(dag, reachableBlocks)
59+
this.parallelConstructor.execute(dag, reachableBlocks)
5360

5461
const { blocksInLoops, blocksInParallels, pauseTriggerMapping } = this.nodeConstructor.execute(
5562
workflow,
@@ -135,7 +142,9 @@ export class DAGBuilder {
135142
)
136143
}
137144

138-
const sentinelStartNode = dag.nodes.get(buildSentinelStartId(id))
145+
const sentinelStartId =
146+
type === 'Loop' ? buildSentinelStartId(id) : buildParallelSentinelStartId(id)
147+
const sentinelStartNode = dag.nodes.get(sentinelStartId)
139148
if (!sentinelStartNode) return
140149

141150
const hasConnections = Array.from(sentinelStartNode.outgoingEdges.values()).some((edge) =>

0 commit comments

Comments
 (0)