drives

package
v0.55.0 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package drives keeps `f10 drive` durable: a record per drive under the storage root, and a lease per task, so two drives, or a drive and `f10 finish`, never act on one task at once.

Index

Constants

View Source
const Dir = "drives"

Dir is the drives directory under a storage root.

Variables

This section is empty.

Functions

func Create

func Create(root string, rec *Record) error

Create writes rec as the next numbered record, setting its number. The file is created exclusively, so two drives started at once get two.

func DriveKey

func DriveKey(n int) string

DriveKey is a drive's own lease, held for the life of its process.

func Path

func Path(root string, n int) string

Path is record n's file under the storage root.

Types

type Answer

type Answer struct {
	Task  string    `yaml:"task"`
	Skill string    `yaml:"skill,omitempty"`
	Text  string    `yaml:"text"`
	At    time.Time `yaml:"at"`
}

An Answer is one taken: by which task, at which skill, when.

type HeldError

type HeldError struct {
	Key    string
	Holder Holder
}

A HeldError is a lease another process holds.

func (HeldError) Error

func (e HeldError) Error() string

type Holder

type Holder struct {
	PID   int
	Drive int  // 0 for `f10 finish` itself
	Watch bool // the daemon's watcher, finishing a task no drive owns
}

A Holder is who holds a lease, as its lock file names it.

func Probe

func Probe(root, key string) (Holder, bool)

Probe reports who holds key's lease, false when nobody does. It takes a shared lock for an instant, which Acquire's retries absorb.

func (Holder) String

func (h Holder) String() string

String names the holder for a refusal: `drive 3 (pid 4242)`.

type Lease

type Lease struct {
	// contains filtered or unexported fields
}

A Lease is a held lock, released by Release or by the process ending.

func Acquire

func Acquire(root, key string, drive int) (*Lease, error)

Acquire takes key's lease for drive (0 for finish) under the storage root, without waiting on a holder: a held one is a HeldError naming it.

func AcquireAs

func AcquireAs(root, key string, h Holder) (*Lease, error)

AcquireAs takes key's lease as h, whose PID is always this process.

func Await added in v0.52.0

func Await(ctx context.Context, root, key string, h Holder, wait time.Duration) (*Lease, error)

Await takes key's lease as h, waiting while another process holds it, until ctx ends or wait passes; then the HeldError names the holder, beside ctx's error when ctx ended.

func (*Lease) Release

func (l *Lease) Release()

Release drops the lease; nil and a second call are fine.

type Outcome

type Outcome struct {
	Row  string `yaml:"row"`
	Code int    `yaml:"code"`
}

An Outcome is a task's row in the drive's report and its exit code.

type Record

type Record struct {
	Number      int        `yaml:"number"`
	Created     time.Time  `yaml:"created"`
	Args        []string   `yaml:"args"` // the command line, --answer, --every, --parallel and --foreground dropped
	Tasks       []Task     `yaml:"tasks"`
	Flow        string     `yaml:"flow,omitempty"`
	Agent       string     `yaml:"agent,omitempty"` // the run-wide --agent (or --model) as typed
	Model       string     `yaml:"model,omitempty"` // the run-wide --model of a record from before profiles, read only
	DriveFinish bool       `yaml:"drive_finish"`
	Cancelled   *time.Time `yaml:"cancelled,omitempty"`
	Session     string     `yaml:"session,omitempty"` // the session that created it, "" from a plain terminal
	// Parallel is the cap on tasks running a skill at once, as the drive
	// took it; a rerun or a resume keeps it unless it passes --parallel
	Parallel int `yaml:"parallel,omitempty"`
	// Answers are given and not yet taken, by task id, "" for the bare one
	Answers  map[string]string `yaml:"answers,omitempty"`
	Answered []Answer          `yaml:"answered,omitempty"`
}

A Record is one drive, kept at <storage root>/drives/<n>.yaml: what it was started with, the answers given, and how each task ended.

func Find

func Find(root string, args []string) (*Record, error)

Find is the newest record started with args that is neither cancelled nor done, nil for none.

func List

func List(root string) ([]*Record, error)

List is every record, newest first. One that will not parse is skipped.

func Read

func Read(root string, n int) (*Record, error)

Read reads record n.

func Update

func Update(root string, n int, change func(*Record)) (*Record, error)

Update applies change to record n under its own lock and writes it back through a rename, so a cancel and the drive's own writes never lose one another. It returns the record as written.

func (*Record) Done

func (r *Record) Done() bool

Done reports every task through with code 0: a drive with nothing left.

func (*Record) Same

func (r *Record) Same(args []string) bool

Same reports whether args names the same drive: the same tasks and flags, order kept, case ignored.

func (*Record) Task

func (r *Record) Task(id string) *Task

Task is the record's task with id, nil for none.

type Task

type Task struct {
	ID      string   `yaml:"id"`               // as typed, a suffix included
	Agent   string   `yaml:"agent,omitempty"`  // its own :profile as typed
	Model   string   `yaml:"model,omitempty"`  // its own :model from before profiles, read only
	After   string   `yaml:"after,omitempty"`  // the base its body's After: line named, as an id
	Skill   string   `yaml:"skill,omitempty"`  // in flight, "" for none
	Queued  bool     `yaml:"queued,omitempty"` // held back by the drive's cap
	Outcome *Outcome `yaml:"outcome,omitempty"`
}

A Task is one task of a drive, as typed, and where it stands.

Jump to

Keyboard shortcuts

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