subreaper

package
v0.1.0-proto2g Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: MPL-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package subreaper implements the PID-1 orphan-reaping obligation (GAPI-DIV-027): the supervisor registers as a child subreaper so orphaned descendants reparent to it instead of pid 1, and a reap loop collects their exit statuses - zombie accumulation is a kernel obligation, not an optimization. Linux-only by nature; non-Linux builds compile and refuse.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupported = errors.New("subreaper: linux-only")

ErrUnsupported: subreaper semantics are a Linux prctl feature.

Functions

func BecomeSubreaper

func BecomeSubreaper() error

BecomeSubreaper marks this process as a child subreaper: orphaned descendants reparent to it rather than to pid 1. Called before any other initialization (Phase 0); when the process IS pid 1 the call is a harmless no-op for correctness but kept for uniformity.

func ReapLoop

func ReapLoop(ctx context.Context, sigchld <-chan os.Signal, notify func(pid int, ws syscall.WaitStatus))

ReapLoop drains terminated children for the supervisor's lifetime. It triggers on SIGCHLD (caller supplies the subscribed channel), on a safety tick (coalesced or pre-subscription signal edges must not strand zombies), and once at startup. Every reaped pid is forwarded to notify with its true wait status; the agent manager decides whether it was a known agent or an adopted orphan.

func ReapLoopWithObserver

func ReapLoopWithObserver(ctx context.Context, sigchld <-chan os.Signal, notify func(pid int, ws syscall.WaitStatus), observe func(DrainEvent))

ReapLoopWithObserver is ReapLoop with a diagnostic seam: observe, when non-nil, is called synchronously with every Wait4 outcome, including the ones the loop itself discards.

It exists for GAPI-DIV-043, whose exit requires the Wait4 errno to be read out of a CI log rather than reproduced locally. observe is called on the loop's goroutine and must not block; a nil observer leaves the loop's control flow identical to what it was before the seam existed, which is deliberate - instrumentation that perturbs the timing of an intermittent failure can spend the failure without explaining it.

Types

type DrainEvent

type DrainEvent struct {
	// Trigger is what woke this drain pass.
	Trigger DrainTrigger
	// Pid is Wait4's return: a positive reaped pid, 0 when a child
	// exists but none is ready, or -1 on error.
	Pid int
	// Status is meaningful only when Pid is positive.
	Status syscall.WaitStatus
	// Err is the Wait4 errno, nil on success. ECHILD - no children at
	// all - is the routine case and not a fault.
	Err error
}

DrainEvent is one Wait4 outcome inside the reap loop, reported to an observer supplied by ReapLoopWithObserver.

The loop's normal operation discards every one of these: a wait that returns no zombie is indistinguishable from one that fails, because both simply end the drain. That is fine for reaping and useless for diagnosis, which is why the observer exists (GAPI-DIV-043).

type DrainTrigger

type DrainTrigger int

DrainTrigger names what woke a drain pass. It exists because the wake source is diagnostic: a zombie collected only ever by DrainTick means the SIGCHLD edge for it was lost, which is a different defect from one where the signal arrived and the wait still came up empty.

const (
	// DrainStartup is the unconditional drain ReapLoop performs before
	// entering its select, so a zombie that died pre-subscription is
	// still collected.
	DrainStartup DrainTrigger = iota
	// DrainSigchld is a drain woken by a delivered SIGCHLD.
	DrainSigchld
	// DrainTick is a drain woken by the safety ticker, which covers
	// coalesced and pre-subscription signal edges.
	DrainTick
)

func (DrainTrigger) String

func (t DrainTrigger) String() string

String renders the trigger for diagnostic output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL