Files
fn_registry/functions/core/subprocess_stream.md
T
egutierrez e3c8979e8d chore: auto-commit (95 archivos)
- cmd/fn/doctor.go
- cmd/fn/main.go
- cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt
- cpp/apps/primitives_gallery/playground/tables/data_table.cpp
- cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp
- cpp/apps/primitives_gallery/playground/tables/data_table_logic.h
- cpp/apps/primitives_gallery/playground/tables/self_test.cpp
- cpp/apps/primitives_gallery/playground/tables/tql.cpp
- cpp/apps/primitives_gallery/playground/tables/viz.cpp
- cpp/apps/primitives_gallery/playground/tables/viz.h
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:50:34 +02:00

3.3 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
subprocess_stream function go core 1.0.0 impure func SubprocessStream(ctx context.Context, name string, args []string, env []string, stdin io.Reader) (<-chan StreamEvent, <-chan StreamResult) Lanza un subproceso y retorna dos canales: uno con StreamEvent (linea de stdout/stderr con timestamp) y otro con un unico StreamResult (ExitCode, Err, DurationMs). Cancelar ctx envia SIGTERM al proceso; si no termina en 2s, SIGKILL.
subprocess
exec
stream
stdout
stderr
process
concurrency
io
primitiva
false error_go_core
bufio
context
fmt
io
os
os/exec
sync
syscall
time
name desc
ctx Contexto de cancelacion. Al cancelar, el proceso recibe SIGTERM; si no muere en 2s, SIGKILL. Usar context.WithTimeout para acotar duracion maxima.
name desc
name Nombre o path del ejecutable a lanzar (ej. 'echo', '/usr/bin/python3').
name desc
args Argumentos del proceso. Puede ser nil o vacio.
name desc
env Variables de entorno adicionales en formato 'KEY=VALUE'. Se concatenan con os.Environ(). Puede ser nil.
name desc
stdin Stdin del proceso. Puede ser nil si el proceso no necesita entrada.
Dos canales: events (<-chan StreamEvent) cerrado cuando ambos pipes EOF; result (<-chan StreamResult) con exactamente un valor cuando el proceso termina. El caller DEBE consumir events hasta cierre o cancelar ctx para evitar bloquear goroutines internas. true
echo stdout llega como evento y ExitCode 0
stderr llega como evento con stream stderr
exit code no-cero se reporta en StreamResult
ctx cancelado termina el proceso
multiples lineas stdout
functions/core/subprocess_stream_test.go functions/core/subprocess_stream.go

Ejemplo

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

events, results := core.SubprocessStream(ctx, "grep", []string{"-rn", "TODO", "."}, nil, nil)

for ev := range events {
    switch ev.Stream {
    case "stdout":
        fmt.Println(ev.Line)
    case "stderr":
        fmt.Fprintln(os.Stderr, "[stderr]", ev.Line)
    }
}

res := <-results
if res.ExitCode != 0 || res.Err != nil {
    log.Printf("grep exit=%d err=%v duration=%dms", res.ExitCode, res.Err, res.DurationMs)
}

Notas

  • El canal events tiene buffer de 64. Si el caller deja de consumir y el buffer se llena, las goroutinas internas se bloquean hasta que haya espacio o el ctx sea cancelado.
  • El scanner de cada pipe tiene un buffer de 1 MB para tolerar lineas muy largas (progreso de CLIs tipo sd-cli, barras ANSI largas).
  • Los structs StreamEvent y StreamResult se declaran en el mismo archivo para que el paquete core los exporte sin imports adicionales.
  • Generaliza el patron de claude_stream_go_core desacoplando el lanzamiento de subprocesos del protocolo especifico de claude (NDJSON/stream-json). claude_stream_go_core puede reimplementarse internamente usando esta funcion como primitiva.
  • cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} crea un process group propio; SIGTERM/SIGKILL se envian con Kill(-pgid, sig) para matar tambien los procesos hijo del hijo.