refactor: move local subworkflows behind runner

Merged
YO
5mo ago
+936-724

Summary

  • move local CLI child workflow execution out of runtime/executor into internal/subflow
  • add a subworkflow router that prefers coordinator-backed execution and falls back to local CLI execution
  • tighten cancellation ownership and boundary types with router fallback coverage

Testing

  • go test ./internal/subflow ./internal/runtime/executor -count=1
  • go test -race ./internal/subflow ./internal/runtime/executor -count=1
  • go test ./internal/runtime/... -count=1
  • go test ./internal/engine ./internal/cmd ./internal/service/worker -count=1
  • go test ./internal/intg -run 'TestInlineSubDAG|TestExternalSubDAG|TestCallSubDAG|TestInlineParams_LocalSubDAGRuntimeCoercion|TestSubDAGParamsReferencedInChildEnv|TestWorkingDir' -count=1
  • go test ./internal/intg/distr -run 'TestSubDAG|TestParams_DistributedSubDAG|TestBaseConfig_SubDAGPropagation|TestCancellation_SubDAG|TestCustomStepTypes_SubDAGBaseConfigPropagation' -count=1
  • make test
  • make lint
  • git diff --check

Summary by cubic

Moved local sub-workflow execution behind a router and LocalCLI runner, removing process management from the executor. Added strict request and workspace validation with cleaner cancellation mapping for safer child runs.

  • Refactors

    • Added internal/subflow router that selects the first runner that accepts a request.
    • Implemented subflow.NewLocalCLI(); internal/runtime/executor no longer spawns/tracks OS processes.
    • Forwarded cancellation intent (graceful/force) and signals to runners; executor tracks only context cancels.
    • Moved action workspace materialization and trace-context injection into LocalCLI.
    • Updated factories to use subflow.NewRouter(subflow.New(...), subflow.NewLocalCLI()) across context, engine, worker, and tests.
  • Bug Fixes

    • Hardened LocalCLI with validation for DAG location and workspace DAG path (normalized and bounds-checked to prevent traversal).
    • Improved cancellation fallback: if no local process is found, request child cancel via DB; error when run DB is missing.

Summary by CodeRabbit

  • New Features
    • Added local CLI execution as an alternative for running child workflows.
  • Improvements
    • Introduced structured cancellation semantics (graceful vs force with signal support).
    • Smarter routing to pick the appropriate sub-workflow execution mode per request.
    • Simplified active-run tracking for more reliable stop/kill behavior.
  • Tests
    • Updated and added tests covering routing, local-run fallback, execution errors, and cancellation scenarios.