daemon

package
v0.53.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package daemon runs drives for one user, outside any session. Each drive is its own `f10 drive --foreground` child in the client's directory and environment, so leases and crash recovery stay the drive's own.

Index

Constants

View Source
const (
	ReasonUpgrade = "upgrade" // the next daemon resumes it
	ReasonStopped = "stopped" // f10 daemon stop: it waits for its next run
)

Why a drive exited ExitDrained.

View Source
const (
	OpHello  = "hello"
	OpRun    = "run"
	OpStatus = "status"
	OpStop   = "stop"
	OpWatch  = "watch"
)

Ops a Request names.

View Source
const ExitDrained = 6

ExitDrained is a drive's exit when it stopped for an upgrade, to be resumed by the next daemon; drive.go's exitDrained.

View Source
const ExitNothingWatched = 7

ExitNothingWatched is a pass's exit when the project has no task left to watch: the daemon stops watching it.

View Source
const NumberFileEnv = "F10_DRIVE_FILE"

NumberFileEnv names the file a drive the daemon runs writes its record number to, once the record is open.

View Source
const Supported = true

Supported reports whether this platform runs a daemon; elsewhere drive runs in the foreground.

Variables

View Source
var ErrNotRunning = errors.New("no f10 daemon is running")

ErrNotRunning is a socket nobody listens on.

View Source
var ErrRunning = errors.New("an f10 daemon is already running")

ErrRunning is a second daemon finding the first one's lease held.

Functions

func ExitPath

func ExitPath(log string) string

ExitPath is the file holding a drive log's exit, once its process ended.

func FindLog

func FindLog(dir, root string, n int) string

FindLog is drive n's newest log under root, from the index; "" for none.

func LogPath

func LogPath(dir string) string

LogPath is the daemon's own log.

func Newer

func Newer(a, b string) bool

Newer reports a strictly newer than b, both release versions (`0.46.0`, `v0.46.0`); a development build is newer than nothing, and nothing is newer than it, so it is replaced only by `f10 daemon stop`.

func RunDir

func RunDir() string

RunDir holds the socket, the locks, the logs and the drained runs: F10_RUN_DIR, else $XDG_RUNTIME_DIR/f10, else ~/.f10/run.

func SocketPath

func SocketPath(dir string) string

SocketPath is where the daemon listens.

Types

type Ensurer

type Ensurer struct {
	Dir     string
	Version string
	// Follow takes any daemon running, whatever its version: a client
	// following a drive into the daemon that resumed it.
	Follow bool
	// Spawn starts a daemon detached; by default `<exe> daemon` in its own
	// session, its output to the daemon log.
	Spawn func(ctx context.Context) error
	// Draining is told when an older daemon is being replaced, Kept when a
	// daemon this client does not replace runs another version.
	Draining, Kept func(running string)
	// StartWait bounds how long a new daemon has to listen; DrainWait how
	// long an old one has to drain.
	StartWait, DrainWait time.Duration
}

An Ensurer finds this user's daemon, or starts one.

func (*Ensurer) Ensure

func (e *Ensurer) Ensure(ctx context.Context) (Reply, error)

Ensure returns a daemon listening, starting one when none does. Only a strictly newer client replaces a running one, so two versions never take turns; the start lease keeps two clients at once to one daemon.

type Exit

type Exit struct {
	Code   int
	Reason string
	Drive  int
}

An Exit is how a drive's process ended: its code, why it drained, and its record number, 0 when it never opened one.

func ReadExit

func ReadExit(log string) (Exit, bool)

ReadExit is how a drive's log ended, false while it runs.

type Reply

type Reply struct {
	Error    string    `json:"error,omitempty"`
	Stopping bool      `json:"stopping,omitempty"` // a stop is draining it
	Version  string    `json:"version,omitempty"`
	PID      int       `json:"pid,omitempty"`
	Started  time.Time `json:"started,omitzero"`
	Log      string    `json:"log,omitempty"`     // run: the drive's log; watch: the project's pass log
	Attach   bool      `json:"attach,omitempty"`  // run: the log is a drive already running
	Runs     []Run     `json:"runs,omitempty"`    // status
	Watches  []Watch   `json:"watches,omitempty"` // status
}

A Reply answers one Request; Error set means it was refused.

func Call

func Call(ctx context.Context, dir string, req Request, wait time.Duration) (Reply, error)

Call sends req to the daemon in dir and reads its reply.

type Request

type Request struct {
	Op      string   `json:"op"`
	Version string   `json:"version,omitempty"` // hello: the client's
	Argv    []string `json:"argv,omitempty"`    // run: drive's arguments, --foreground added by the daemon
	Dir     string   `json:"dir,omitempty"`     // run: where the drive was typed; watch: the main checkout
	Root    string   `json:"root,omitempty"`    // run, watch: the storage root, telling projects apart
	Env     []string `json:"env,omitempty"`     // run, watch: the allowlisted environment
	Key     string   `json:"key,omitempty"`     // run: the record's command line, joined; "" never attaches
	Resume  int      `json:"resume,omitempty"`  // run: the record --resume names
	Drain   bool     `json:"drain,omitempty"`   // stop: let each drive reach a tick boundary
	Upgrade bool     `json:"upgrade,omitempty"` // stop: a newer daemon follows and resumes the drained drives
}

A Request is one call: an op and what it needs.

type Run

type Run struct {
	Root  string    `json:"root"`
	Dir   string    `json:"dir"`
	Drive int       `json:"drive,omitempty"` // 0 until the drive printed its number
	PID   int       `json:"pid"`
	Since time.Time `json:"since"`
	Log   string    `json:"log"`
}

A Run is one drive process the daemon supervises.

type Server

type Server struct {
	Dir     string // the run dir
	Version string
	// Child is the command a drive's argv runs as: by default the daemon's
	// own binary, `drive --foreground <argv>`.
	Child func(argv []string) (string, []string)
	// Pass is the command one watch pass runs as in a project's main
	// checkout: by default the daemon's own binary, `watch --pass`.
	Pass       func(dir string) (string, []string)
	WatchEvery time.Duration // how often each watched project gets a pass
	Idle       time.Duration // no drive, no watched project and no call this long: exit
	DrainWait  time.Duration // how long a drain waits for drives before SIGTERM
	Tick       time.Duration // how often idleness is checked
	Log        *log.Logger
	// contains filtered or unexported fields
}

A Server supervises drive processes for one user.

func (*Server) Serve

func (s *Server) Serve(ctx context.Context) error

Serve holds the daemon's lease, listens, and supervises until it is idle, stopped, or ctx ends (a drain).

type Watch

type Watch struct {
	Root string    `json:"root"`
	Dir  string    `json:"dir"`           // the main checkout
	Last time.Time `json:"last,omitzero"` // when the last pass ended
	Exit int       `json:"exit"`          // its exit code
	Log  string    `json:"log"`           // the project's pass log
}

A Watch is one project the daemon watches for tasks no drive owns: a `watch --pass` in its main checkout every few minutes.

Jump to

Keyboard shortcuts

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