Skip to content
This repository was archived by the owner on Apr 11, 2026. It is now read-only.

Commit 972b113

Browse files
z23ccclaude
andcommitted
refactor(flowctl): remove duplicate cycle detection from DAG construction [fn-110.4]
Move cycle detection out of from_tasks() — callers now call detect_cycles() explicitly. This eliminates the redundant Kahn's algorithm run during DAG construction. Updated stats.rs to add explicit cycle check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e6c99bf commit 972b113

2 files changed

Lines changed: 10 additions & 12 deletions

File tree

flowctl/crates/flowctl-cli/src/commands/stats.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,12 @@ pub fn cmd_dag(json_flag: bool, epic_id: Option<String>) {
353353
};
354354

355355
let dag = match flowctl_core::TaskDag::from_tasks(&tasks) {
356-
Ok(d) => d,
356+
Ok(d) => {
357+
if let Some(cycle) = d.detect_cycles() {
358+
error_exit(&format!("Cycle detected in DAG: {}", cycle.join(" -> ")));
359+
}
360+
d
361+
}
357362
Err(e) => error_exit(&format!("Failed to build DAG: {}", e)),
358363
};
359364

flowctl/crates/flowctl-core/src/dag.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,7 @@ impl TaskDag {
6767
}
6868
}
6969

70-
let dag = TaskDag { graph, index };
71-
72-
// Phase 3: cycle detection.
73-
if let Some(cycle) = dag.detect_cycles() {
74-
let cycle_str = cycle.join(" -> ");
75-
return Err(CoreError::CycleDetected(cycle_str));
76-
}
77-
78-
Ok(dag)
70+
Ok(TaskDag { graph, index })
7971
}
8072

8173
/// Return task IDs whose dependencies are all satisfied.
@@ -552,8 +544,9 @@ mod tests {
552544
make_task("b", &["a"]),
553545
make_task("c", &["b"]),
554546
];
555-
let err = TaskDag::from_tasks(&tasks).unwrap_err();
556-
assert!(matches!(err, CoreError::CycleDetected(_)));
547+
// from_tasks no longer detects cycles — callers must use detect_cycles()
548+
let dag = TaskDag::from_tasks(&tasks).unwrap();
549+
assert!(dag.detect_cycles().is_some());
557550
}
558551

559552
// ── ready_tasks ─────────────────────────────────────────────────

0 commit comments

Comments
 (0)