Skip to content

stnmrshx/go-processmanager

Repository files navigation

go-processmanager

Process manager for Go — start, monitor, and stop subprocesses with graceful shutdown, process group management, and PID-based state persistence.

Quick start

import "github.com/stnmrshx/go-processmanager"

p := process.New(
    process.WithName("/bin/bash"),
    process.WithArgs("-c", "while true; do echo hello; sleep 1; done"),
    process.WithTemporaryStateDir(),
)

if err := p.Run(); err != nil {
    log.Fatal(err)
}

defer p.Stop()

// Wait for the process to exit or call p.IsAlive() / p.ExitCode()
<-p.Done()

Features

  • Graceful shutdown — SIGTERM with configurable timeout, then SIGKILL if needed (default 15s). Default kill signal is SIGKILL (9), customizable via WithKillSignal().
  • Process group killing — by default the entire process group is targeted (negative PID on Unix). Disable with WithKillProcessGroup(false).
  • PID-based state — all process metadata (PID, stdout, stderr, exit code, errors) is stored in a state directory (StateDir). Recreate a Process pointing at the same dir to attach to an existing one.
  • Zombie reaping — on Linux, calls PR_SET_CHILD_SUBREAPER so orphaned child processes are cleaned up. No-op on other platforms.
  • Subprocess stdio — stdout and stderr are appended to files in the state directory via NewLog(). Stdin can be wired via WithSTDIN().

Architecture

config.go        — Config struct, DefaultConfig(), Option type
options.go       — Functional options (WithName, WithArgs, WithStateDir, etc.)
process.go       — Core Process: Run(), Stop(), IsAlive(), Done(), ExitCode()
writer.go        — NewLog(path) opens an append-mode log file
process_unix.go  — Unix build tag: new process group, negative PID kill, zombie reaping
process_windows.go — Windows build tag: direct Kill via os.FindProcess, no-op reaping
subreaper_linux.go   — Linux-specific SetSubreaper() via unix.Prctl(PR_SET_CHILD_SUBREAPER)
subreaper_other.go   — No-op SetSubreaper() on non-Linux

API reference

Function / Method Purpose
process.New(opts...) Create a new Process with functional options
p.Run() Start the subprocess; returns error if already running
p.Stop() Send KillSignal (SIGTERM by default), wait GracefulTimeout, then SIGKILL
p.IsAlive() Check if process is still running via PID
p.Done() Channel closed when the process exits
p.ExitCode() Read the exit code from state directory
p.StateDir() Return the path to the state directory
p.StdoutPath() / p.StderrPath() Paths to stdout/stderr log files

Functional options

Option Purpose
WithName(string) Executable path or name
WithArgs(...string) Command-line arguments (appended)
WithStateDir(string) Explicit state directory path
WithTemporaryStateDir() Create a temporary state directory
WithWorkDir(string) Working directory for the subprocess
WithEnvironment(...string) Environment variables (replaces os.Environ())
WithSTDIN(*os.File) Stdin file handle
WithKillSignal(int) Kill signal number (default 9 / SIGKILL)
WithGracefulTimeout(time.Duration) Timeout after SIGTERM before SIGKILL (default 15s)
WithKillProcessGroup(bool) Target entire process group (default true)

Running tests

go test ./...

Tests use Ginkgo / Gomega with dot-imports. Several specs use Eventually() with 2m timeouts.

Build tags

Tag Effect
unix Process groups, negative PID kill, zombie reaping
windows Direct Kill via os.FindProcess, no-op reaping
linux PR_SET_CHILD_SUBREAPER subreaper
!linux No-op SetSubreaper

License

MIT License 2026 StnMrshx — see LICENSE.

About

Process manager for Go — start, monitor, and stop subprocesses with graceful shutdown, process group management, and PID-based state persistence for self purpose yhaaaaa.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages