A concurrent Linux service orchestrator in Go that launches multi-service dev workflows from declarative YAML and cleans them up deterministically.
Use the distro-specific guides outside this README:
- Fedora:
docs/README-fedora.md - Non-Fedora Linux:
docs/README-linux.md
graph LR
A[CLI: devflow start] --> B[Orchestrator Daemon]
B --> C{Topo Sort}
C --> D[Service A]
C --> E[Service B]
C --> F[Service C]
D --> G[(state.json)]
E --> G
F --> G
B --> H[(logs)]
B --> I[(IPC socket)]
- Concurrency: goroutines +
sync.WaitGroup+ mutex-protected process map for non-blocking orchestration. - Dependency integrity: Kahn topological sort enforces startup order; cleanup runs in reverse order.
- Linux-native operations: daemonized orchestrator (
setsid) and terminal-aware service spawning. - Resilience: stale PID filtering and explicit error propagation in storage/bootstrap paths.
- Quality gate: local pre-commit + CI workflow run format checks, tests, and race tests.
devflow build -f workflows/workflow.yml
devflow start -f workflows/workflow.yml
devflow active
devflow stop <workflow_name>Create a file like workflows/myapp.yml.
- Top level:
workflow_nameservices
- Per service:
command
- Top level:
logon_close
- Per service:
argspathdepends_onportdetachedlogvarson_close
workflow_name: myapp
log: true
services:
db:
command: docker
args: ["compose", "up", "-d", "postgres"]
path: ~/myapp/infra
port: 5432
api:
command: go
args: ["run", "./cmd/api"]
path: ~/myapp/backend
depends_on: ["db"]workflow_name: unique workflow identifier used in state/log naming.services: map of service names to service definitions.command: executable/binary to run (example:go,docker,npm).args: argument array passed tocommand.path: working directory before running the command (~supported).depends_on: service names that must start first.port: port readiness check before dependents start.detached: run silently in background (true) instead of new terminal.log: enable logging for that service.vars: environment key/value pairs for that service process.on_close: cleanup command(s) to run on service/workflow shutdown.
services:
backend:
command: go
args: ["run", "./cmd/api"]
path: ~/myapp/backend
on_close:
- command: pkill
args: ["-f", "cmd/api"]DevFlow uses:
- Primary:
~/.config/devflow/ - Fallback:
~/.devflow/(ifos.UserConfigDir()is unavailable)
Created files/folders include:
flows/<name>.yml: registered workflow snapshots fromdevflow buildstorage/workflows.json: workflow registrystorage/<workflow>.state.json: active service PID/state tracking<workflow>.pid: daemon PID file<workflow>.sock: daemon IPC socketlogs/devflow-daemon-<workflow>-<timestamp>.log: daemon logslogs/<workflow>-<timestamp>/<service>.log: per-service logs (when logging enabled)
devflow build -f <file>devflow start -f <file>devflow start -n <registered_name>devflow activedevflow stop <workflow|workflow.service>devflow lsdevflow rm <workflow_name>
Run all checks:
./testing/scripts/pre_commit_check.shInstall local pre-commit hook:
./testing/scripts/install_pre_commit_hook.shCI runs the same gate on push/PR: .github/workflows/test.yml.
- Race-risk orchestration logic required explicit synchronization and race-test automation.
- External process management needed robust state hygiene (
signal 0liveness checks + cleanup on exit). - Error handling quality improved significantly by removing panic/silent-failure paths in bootstrap and storage code.
MIT (LICENSE).