Skip to content

Fix pipeline deadlock on cross-team task dependencies#697

Merged
Iron-Ham merged 1 commit into
mainfrom
Iron-Ham/fix-pipeline-cross-team-dependency-deadlock
Mar 21, 2026
Merged

Fix pipeline deadlock on cross-team task dependencies#697
Iron-Ham merged 1 commit into
mainfrom
Iron-Ham/fix-pipeline-cross-team-dependency-deadlock

Conversation

@Iron-Ham
Copy link
Copy Markdown
Owner

Summary

  • Fixed pipeline deadlock: pipeline.Decompose grouped tasks into execution teams using only file-affinity (union-find on shared files). Tasks with DependsOn relationships but disjoint files landed in separate teams. Since TaskQueue.isClaimable() only resolves dependencies within its own task set, cross-team dependencies were permanently unsatisfiable — deadlocking the pipeline after the first dependency group completed.
  • Added unknown dep ID guard: The dependency union loop now skips DependsOn entries referencing task IDs not in the plan, preventing silent union-find corruption via phantom root nodes.
  • Renamed groupByFileAffinitygroupByAffinity to reflect its expanded responsibility (files + dependency edges).

Root Cause

The decomposer's union-find only unioned tasks sharing files. When task A (Swift files) and task B (GraphQL files) had no file overlap, they landed in different execution teams. Downstream tasks depending on both A and B were placed in teams where the dep IDs didn't exist in the local TaskQueue, causing isClaimable() to return false permanently.

Fix

Union tasks along DependsOn edges in addition to file edges during decomposition. This ensures all task-level dependencies are resolvable within a single team's queue.

Test plan

  • TestDecompose_DependencyGrouping — direct dependency with disjoint files → same team
  • TestDecompose_TransitiveDependencyGrouping — transitive chain (t3→t2→t1) with disjoint files → all in one team
  • TestDecompose_DisjointDepsAndFiles — reproduces the exact real-world scenario (swipe framework + GraphQL codegen + wiring task)
  • TestDecompose_UnknownDependencyIgnored — stale dep ID is skipped, no phantom union-find corruption
  • All existing tests pass (no regressions)
  • go test -race ./... passes
  • go vet ./... clean
  • gofmt -d . clean

@Iron-Ham Iron-Ham marked this pull request as ready for review March 21, 2026 03:41
The decomposer (pipeline.Decompose) grouped tasks into execution teams
using only file-affinity via union-find. Tasks with DependsOn
relationships but disjoint files landed in separate teams. Since each
team's TaskQueue.isClaimable() only resolves dependencies within its
own task set, cross-team dependencies were permanently unsatisfiable,
deadlocking the pipeline after the first dependency group completed.

Fix: union tasks along DependsOn edges in addition to shared-file
edges, ensuring all task-level dependencies are resolvable within a
single team's queue. Guard against unknown dep IDs to prevent silent
union-find corruption via phantom root nodes.

Rename groupByFileAffinity -> groupByAffinity to reflect expanded
responsibility.
@Iron-Ham Iron-Ham force-pushed the Iron-Ham/fix-pipeline-cross-team-dependency-deadlock branch from 8742241 to 3f7f1e7 Compare March 21, 2026 03:42
@Iron-Ham Iron-Ham merged commit 35ba954 into main Mar 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant