process
Process supervisor primitives — start, stop, signal, wait, restart. The
same call shape that runs a one-shot exec also drives long-lived daemons
with health endpoints. Built on core/go so every operation
returns a Result.
Install
Section titled “Install”go get dappco.re/go/process@latestImport
Section titled “Import”import "dappco.re/go/process"One-shot exec
Section titled “One-shot exec”r := process.Start(ctx, "git", "rev-parse", "HEAD")if !r.OK { return r }sha := r.Value.(string)For more control — environment, working directory, stdout/stderr capture
— pass RunOptions:
r := process.StartWithOptions(ctx, process.RunOptions{ Command: "ffmpeg", Args: []string{"-i", "in.mov", "out.mp4"}, Env: map[string]string{"PATH": "/usr/local/bin:/usr/bin"}, Dir: "/tmp/encode", Capture: true,})if !r.OK { return r }out := r.Value.(*process.ExecResult)fmt.Println(out.Stdout)Long-lived daemon
Section titled “Long-lived daemon”Daemon wraps a command with a supervisor loop — restart on exit, ring
buffer for the last N stdout/stderr lines, optional health endpoint:
d := process.NewDaemon(process.DaemonOptions{ Name: "indexer", Command: "/usr/local/bin/indexer", Args: []string{"--watch", "/srv/data"}, RestartPolicy: process.RestartAlways, RestartBackoff: 5 * time.Second, LogBufferSize: 1024,})
if r := d.Start(ctx); !r.OK { return r }defer d.Stop(ctx)
// Tail the recent logs at any timelines := d.RecentLogs(50)For HTTP introspection:
hs := process.NewHealthServer(":7100")hs.Attach(d)go hs.Listen(ctx)
// GET /health → JSON daemon status// GET /logs → recent ring-buffer linesService + Registry
Section titled “Service + Registry”A Registry tracks every Daemon a Core registered so multi-process
applications get a single view of who’s alive. The Service factory plugs
the registry directly into the Core lifecycle:
c := core.New(core.Options{})
svc := process.NewService(process.Options{ Dir: "/var/run/myapp",})
if r := svc(c); !r.OK { return r }
// Discover registered daemonsrunning := process.NewRegistry("/var/run/myapp").List()Cross-platform compile
Section titled “Cross-platform compile”Unix-only syscall.Kill, syscall.SIGKILL, SysProcAttr{Setpgid: true},
and WaitStatus.Signaled() have all moved behind a small platform-helper
triplet — platform.go declares the shared signatures, platform_unix.go
keeps the original POSIX semantics, and platform_windows.go provides
the equivalent or best-effort behaviour:
| Helper | Unix | Windows |
|---|---|---|
processSignal(pid, sig) | syscall.Kill(pid, sig) | os.FindProcess(pid).Signal(sig) |
processKillGroup(pid) | syscall.Kill(-pid, SIGKILL) | best-effort leader-only kill |
processSignalGroup(pid, sig) | syscall.Kill(-pid, sig) | Ok(nil) stub — no Win32 equivalent |
applyProcessGroup(cmd) | SysProcAttr{Setpgid: true} | no-op |
exitWasSignaled(state) | WaitStatus.Signaled() | false |
The Service compiles clean for GOOS=windows GOARCH=amd64 and the smoke
tests cover both targets. Full process-group semantics on Windows (Job
Objects) are Phase 2; today’s stubs are sufficient for tray-lifecycle
and supervisor-restart cases.
Sibling packages
Section titled “Sibling packages”go/io— file-system Medium for daemon log persistencego/store— persisted daemon registry statego/log— structured logging that daemons emit through
Source
Section titled “Source”github.com/dappcore/go-process — full source, issues, and releases.