fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
131 lines
3.8 KiB
Markdown
131 lines
3.8 KiB
Markdown
---
|
|
id: "0007b"
|
|
title: "Process manager: spawn, wait, kill, status"
|
|
status: completado
|
|
type: feature
|
|
domain: []
|
|
scope: multi-app
|
|
priority: alta
|
|
depends: []
|
|
blocks: []
|
|
related: []
|
|
created: 2026-05-17
|
|
updated: 2026-05-17
|
|
tags: []
|
|
---
|
|
# 0007b — Process manager: spawn, wait, kill, status
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | 0007b |
|
|
| **Estado** | pendiente |
|
|
| **Prioridad** | alta |
|
|
| **Tipo** | feature |
|
|
|
|
## Dependencias
|
|
|
|
| ID | Título | Estado | Requerido |
|
|
|----|--------|--------|-----------|
|
|
| 0007a | Funciones core del DAG engine | pendiente | Si |
|
|
|
|
**Bloqueada por:** `#0007a`
|
|
|
|
**Desbloquea:** `#0007e`
|
|
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
Funciones impuras para gestionar procesos hijo: lanzar, esperar, matar, consultar estado. Son los bloques que el executor usara para correr cada step de un DAG.
|
|
|
|
## Contexto
|
|
|
|
- Cada step de un DAG se ejecuta como un proceso hijo (`os/exec`)
|
|
- Necesitamos captura de stdout/stderr, timeout, señales (SIGTERM/SIGKILL)
|
|
- Deben ser funciones atomicas — el executor las compone
|
|
- Dominio `infra` porque gestionan recursos del sistema
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
functions/infra/
|
|
├── process_spawn.go — NEW: lanza proceso, retorna PID + pipes
|
|
├── process_spawn.md
|
|
├── process_wait.go — NEW: espera proceso con timeout
|
|
├── process_wait.md
|
|
├── process_kill.go — NEW: envia señal a proceso (SIGTERM, SIGKILL)
|
|
├── process_kill.md
|
|
├── process_status.go — NEW: consulta estado de PID (running, exited, code)
|
|
├── process_status.md
|
|
|
|
types/infra/
|
|
├── process_handle.md — NEW: PID, stdin/stdout/stderr pipes, start_time
|
|
├── process_result.md — NEW: exit_code, stdout, stderr, duration_ms
|
|
```
|
|
|
|
### Patron pure core / impure shell
|
|
|
|
- `core/` — No aplica en este issue
|
|
- `infra/` — Todas impuras (spawn procesos, I/O con OS)
|
|
- `error_type`: `error_go_core` para todas
|
|
|
|
## Tareas
|
|
|
|
### Fase 1: Tipos
|
|
|
|
- [ ] **1.1** Definir `ProcessHandle` — pid, cmd, start_time, working_dir
|
|
- [ ] **1.2** Definir `ProcessResult` — exit_code, stdout, stderr, duration_ms, killed
|
|
|
|
### Fase 2: Funciones
|
|
|
|
- [ ] **2.1** `process_spawn` — ejecuta comando con args, env, working_dir. Retorna ProcessHandle. No bloquea.
|
|
- [ ] **2.2** `process_wait` — espera a que el proceso termine o timeout. Retorna ProcessResult.
|
|
- [ ] **2.3** `process_kill` — envia SIGTERM, espera grace period, luego SIGKILL si sigue vivo
|
|
- [ ] **2.4** `process_status` — consulta si el PID sigue corriendo, retorna estado
|
|
|
|
### Fase 3: Tests
|
|
|
|
- [ ] **3.1** Tests: spawn+wait de `echo hello`, timeout con `sleep 999`, kill de proceso largo
|
|
- [ ] **3.2** Tests: captura correcta de stdout/stderr, exit codes no-zero
|
|
|
|
### Fase 4: Cleanup
|
|
|
|
- [ ] `fn index` y verificar IDs
|
|
- [ ] Verificar error_type en todas las funciones impuras
|
|
|
|
---
|
|
|
|
## Ejemplo de uso
|
|
|
|
```go
|
|
handle, err := process_spawn(ProcessSpawnInput{
|
|
Command: "python3",
|
|
Args: []string{"script.py", "--flag"},
|
|
Env: []string{"API_KEY=xxx"},
|
|
WorkingDir: "/home/lucas/project",
|
|
})
|
|
|
|
result, err := process_wait(handle, 30*time.Second) // timeout 30s
|
|
// result.ExitCode == 0, result.Stdout == "output..."
|
|
|
|
// O matar si tarda demasiado
|
|
process_kill(handle, 5*time.Second) // SIGTERM, 5s grace, luego SIGKILL
|
|
```
|
|
|
|
## Decisiones de diseno
|
|
|
|
- **Spawn no bloquea**: retorna handle inmediatamente, wait es separado — permite al executor lanzar steps en paralelo
|
|
- **Kill con grace period**: SIGTERM primero, espera, SIGKILL si no murio — comportamiento estandar de process managers
|
|
- **Stdout/stderr como strings**: para steps cortos. Para steps con output grande, futuro: streaming a archivo
|
|
|
|
## Criterios de aceptacion
|
|
|
|
- [ ] Spawn y wait funcionan con comandos reales
|
|
- [ ] Timeout mata el proceso correctamente
|
|
- [ ] Kill con grace period funciona
|
|
- [ ] Exit codes se capturan correctamente
|
|
- [ ] Tests pasan
|
|
- [ ] Indexado en registry.db
|