multiplexer¶
import "github.com/jbcom/radioactive-ralph/internal/multiplexer"
Package multiplexer detaches the Ralph supervisor from the calling shell so `radioactive_ralph run –detach` returns control to the operator while the supervisor keeps running.
Three backends are probed in order, from strongest to weakest:
tmux — if $TMUX is set or `tmux` is on PATH. Operator can later re-attach with `tmux attach -t <session>` to see the live supervisor output. This is the recommended backend on every platform that has it.
screen — fallback if tmux is unavailable. Less featureful UI but same attach/detach model.
setsid + double-fork — pure-stdlib fallback via syscalls. Runs the supervisor as an orphaned process inherited by init (pid 1) with stdin/stdout/stderr redirected to a log file. No re-attach is possible in this mode — operators use `radioactive_ralph attach` (Unix socket) or tail the log directly.
Service-installed variants (brew services, launchd, systemd –user) always invoke the supervisor in –foreground mode, bypassing this package entirely. The service manager itself is the supervisor’s parent.
Index¶
Variables¶
ErrNoBackend is returned if Detect cannot find a usable backend. On current macOS/Linux this essentially never happens because the setsid fallback always succeeds.
var ErrNoBackend = errors.New("multiplexer: no backend available (no tmux, no screen, no setsid)")
type Backend¶
Backend identifies which detach mechanism a Detacher will use.
type Backend int
const (
// BackendUnknown is the zero value; only returned by Detect when
// an explicit override asked for an unknown kind.
BackendUnknown Backend = iota
// BackendTmux uses `tmux new-session -d` for full detach with later re-attach.
BackendTmux
// BackendScreen uses `screen -dmS` for detach with later re-attach.
BackendScreen
// BackendSetsid uses syscall.Setsid + double-fork for pure-POSIX detach
// with no re-attach UI (operator uses `radioactive_ralph attach` or tails the log).
BackendSetsid
)
func (Backend) String¶
func (b Backend) String() string
String returns a human-friendly backend name.
type Detacher¶
Detacher encapsulates one chosen backend and knows how to spawn the supervisor command detached from the calling shell.
type Detacher struct {
// contains filtered or unexported fields
}
func Detect¶
func Detect(opts ...DetectOption) (*Detacher, error)
Detect probes the environment and returns a Detacher bound to the strongest available backend.
func (*Detacher) Backend¶
func (d *Detacher) Backend() Backend
Backend reports which detach mechanism this Detacher is bound to.
func (*Detacher) SpawnDetached¶
func (d *Detacher) SpawnDetached(req SpawnRequest) (Spawned, error)
SpawnDetached spawns req fully detached using the Detacher’s chosen backend. See the package-level comment for the precedence order.
type DetectOption¶
DetectOption customises Detect. These compose for tests where we need to force a specific backend or swap out the probe.
type DetectOption func(*Detacher)
func WithGetenv¶
func WithGetenv(fn func(string) string) DetectOption
WithGetenv overrides os.Getenv. Used by tests to toggle $TMUX.
func WithLookPath¶
func WithLookPath(fn func(string) (string, error)) DetectOption
WithLookPath overrides exec.LookPath. Tests pass a stub that reports specific binaries as missing to exercise each fallback branch.
func WithPreferredBackend¶
func WithPreferredBackend(b Backend) DetectOption
WithPreferredBackend forces a specific backend if available; Detect will return ErrNoBackend if the preferred one probes as missing. Used by `radioactive_ralph run –multiplexer X` CLI flag and by init wizard when the operator has explicitly chosen a backend.
type SpawnRequest¶
SpawnRequest describes a process the supervisor wants spawned detached. All file paths must be absolute; SpawnDetached does no path resolution.
type SpawnRequest struct {
// Name is the command to exec. Usually the absolute path to
// radioactive_ralph itself, e.g. "/usr/local/bin/radioactive_ralph".
Name string
// Args are passed to Name. Typically something like
// ["_supervisor", "--variant", "green", "--repo-root", "..."].
Args []string
// SessionName is the human identifier (tmux session name, screen
// session name, or a tag written into the log file header for setsid
// mode). Should be unique per per-variant supervisor on this host;
// the supervisor package generates it as
// `radioactive_ralph-<variant>-<repohash[:8]>`.
SessionName string
// LogPath receives stdout + stderr of the spawned supervisor (setsid
// mode uses it as the primary record; tmux/screen sessions also
// `pipe-pane` / `logfile` to it for `radioactive_ralph attach` fallback tailing).
LogPath string
// Env is passed through to the detached process. Nil means inherit
// the current environment.
Env []string
// Dir sets the working directory of the detached process. Supervisor
// is typically spawned with Dir = operator's repo root.
Dir string
}
type Spawned¶
Spawned is the return value of SpawnDetached. Descriptor names how to re-reach the detached process (tmux/screen session name), and PID carries the child PID for backends that know it synchronously.
SpawnDetached itself runs req.Name with req.Args fully detached. For tmux/screen it blocks only long enough to invoke the multiplexer’s own detach command (~millisecond). For setsid it performs a double-fork and returns when the grandchild has execve’d.
type Spawned struct {
// Descriptor names how to re-reach the detached process. For tmux:
// the session name passed to `tmux attach -t <name>`. For screen:
// the session name passed to `screen -r <name>`. For setsid: the
// empty string (no re-attach available; use `radioactive_ralph attach` socket).
Descriptor string
// PID is the process ID of the detached supervisor if the backend
// knows it immediately. tmux/screen may not populate this
// synchronously — call ralph status or read the PID file written by
// the supervisor itself.
PID int
}
Generated by gomarkdoc