Help us shape the future of Go! Take the 2026 Go Developer Survey

daemon

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrSupervisorAlreadyRunning = errors.New("supervisor already running for this config directory")

Functions

func Daemonize

func Daemonize(outLog, errLog, controlURL string, manageACL, noAutoProvision, mcp bool) (int, error)

Daemonize re-launches the current binary in the background with the serve command. controlURL, manageACL, noAutoProvision and mcp are propagated to the child so the re-executed foreground `serve` observes the same opt-ins as the parent; a dropped --manage-acl or --mcp would silently disable the documented opt-in in daemon mode.

func IsForeignProcessFromPIDFile

func IsForeignProcessFromPIDFile(path string) bool

IsForeignProcessFromPIDFile reports true only when the PID file names a live process that is provably a different program. A process that merely cannot be identified returns false, so the conservative "identity unverified" treatment stays the default and only positive proof moves a caller off it.

func IsPIDFileMissing

func IsPIDFileMissing(path string) bool

IsPIDFileMissing reports whether no PID file exists at path: no daemon was started from this config directory, or it exited and removed its file. Status reports that as absent rather than unknown. It says nothing about a PID file that exists but cannot be read, and it is not a reason to delete other PID artifacts (IsProcessAbsentFromPIDFile decides that).

func IsProcessAbsentFromPIDFile

func IsProcessAbsentFromPIDFile(path string) bool

IsProcessAbsentFromPIDFile reports true only when a readable positive PID is conclusively absent. Callers must preserve PID artifacts for unknown or permission-denied liveness results.

func IsProcessRunning

func IsProcessRunning(pid int) bool

IsProcessRunning reports whether pid is alive and belongs to the TSLink product. Callers with a PID-file path should use IsRunning so the recorded process-instance identity is also checked.

func IsRunning

func IsRunning(path string) bool

IsRunning reports whether the process referenced by path is alive.

func ReadPID

func ReadPID(path string) (int, error)

ReadPID reads and parses a PID file.

func RemovePID

func RemovePID(path string)

RemovePID removes the PID file on a best-effort basis.

func RunSupervisor

func RunSupervisor(ctx context.Context, clock SupervisorClock, start func() (SupervisorChild, error), record func(SupervisorState) error) error

RunSupervisor restarts every unexpected exit, including exit zero. Only an explicit cancellation stops supervision. Eight consecutive runs shorter than five minutes trip a persistent breaker; the caller records it and exits zero so the scheduler's backstop cannot undo the breaker.

func StopDaemon

func StopDaemon(pidPath string) error

StopDaemon sends SIGTERM to the daemon and waits up to 5 seconds for exit.

func WithPIDLock

func WithPIDLock(path string, fn func() error) error

WithPIDLock holds the PID-file lock while fn runs.

func WithSupervisorLock

func WithSupervisorLock(path string, run func() error) error

WithSupervisorLock holds a nonblocking, process-lifetime config lock. Keep the lock file after exit: unlinking it would let contenders lock two inodes.

func WritePID

func WritePID(path string) error

WritePID writes the current process PID and a process-instance identity sidecar, with no build-identity report at all: neither BuildVersion nor Executable is set, so both stay omitted from the wire (see processIdentityRecord). This keeps WritePID's on-disk output exactly what it was before build-identity reporting existed, for its remaining callers (tests, and any future caller with no build-identity evidence to report). The PID file remains numeric for compatibility with older clients.

func WritePIDForProcess

func WritePIDForProcess(path string, pid int) error

WritePIDForProcess writes a numeric PID file. It is also used for the short-lived ready signal, so process identity is intentionally written only by WritePID at the daemon's canonical PID path.

func WritePIDWithBuildIdentity

func WritePIDWithBuildIdentity(path, buildVersion string) error

WritePIDWithBuildIdentity writes the current process PID and a process-instance identity sidecar carrying a reporting-only build identity, so a later 'tslink doctor' invocation can compare what actually started against what CLI it is running now. buildVersion is supplied by the caller: only cmd knows the linked release version (see selfBuildIdentity in cmd). The running executable path is resolved here the same way verifyProcessProduct resolves a peer process's executable, best-effort — a resolution failure just leaves the field empty, because this is reporting-only and must never block daemon startup (see the BuildVersion/Executable comment on processIdentityRecord).

Types

type ProcessBuildIdentity

type ProcessBuildIdentity struct {
	BuildVersion string
	Executable   string
}

ProcessBuildIdentity is the reporting-only subset of the daemon's identity sidecar exposed for 'tslink doctor' build-skew comparisons. Both fields are zero-valued when the sidecar is missing, unreadable, malformed, or simply predates build-identity reporting: callers must render that as "unknown," never as a build identity equal to any other zero value.

func ReadProcessBuildIdentity

func ReadProcessBuildIdentity(pidPath string) ProcessBuildIdentity

ReadProcessBuildIdentity reads the build-identity subset of the process identity sidecar at pidPath, for daemon/CLI build-skew reporting. It never participates in IsRunning, IsProcessRunning, or any liveness/identity verification decision (see verifyProcessIdentity): a missing, unreadable, or malformed sidecar simply yields a zero-value ProcessBuildIdentity, not an error a caller should act on. The sidecar's process-identity version and product fields are deliberately not checked here either, for the same reason — this is a best-effort report, not a gate.

type SupervisorChild

type SupervisorChild struct {
	PID  int
	Wait func() error
	Stop func() error
}

SupervisorChild owns a direct child. Stop must be bounded and Wait must reap it. No global test seam is read by the Wait goroutine.

type SupervisorClock

type SupervisorClock struct {
	Now   func() time.Time
	Sleep func(context.Context, time.Duration) error
}

func NewSupervisorClock

func NewSupervisorClock() SupervisorClock

NewSupervisorClock captures the seam on the calling goroutine.

type SupervisorState

type SupervisorState struct {
	State     string        `json:"state"`
	DaemonPID int           `json:"daemon_pid,omitempty"`
	Failures  int           `json:"failures"`
	Backoff   time.Duration `json:"backoff_ns,omitempty"`
	NextStart time.Time     `json:"next_start,omitempty"`
	Reason    string        `json:"reason,omitempty"`
	UpdatedAt time.Time     `json:"updated_at"`
}

Jump to

Keyboard shortcuts

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