state

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrLockHeld = errors.New("lock is held by another process")

ErrLockHeld is returned by tryAcquireLock when the lock file exists and its holder process is still alive. Callers typically present this as a "already in progress, try again later" message to the user.

Functions

This section is empty.

Types

type ModelState

type ModelState struct {
	Name        string    `json:"name"`
	PID         int       `json:"pid"`
	Port        int       `json:"port"`
	Host        string    `json:"host"`
	ConfigPath  string    `json:"config_path"`
	LogFile     string    `json:"log_file"`
	StartedAt   time.Time `json:"started_at"`
	ProfileName string    `json:"profile_name"`
	Status      string    `json:"status"` // "running" | "stopped" | "error"
	BinaryPath  string    `json:"binary_path"`
	Backend     string    `json:"backend"` // "llama" | "sd" | "whisper"
}

type StateFile

type StateFile struct {
	Version int                    `json:"version"`
	Models  map[string]*ModelState `json:"models"`
}

type Store

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

func NewStore

func NewStore() *Store

func (*Store) EnsureDir

func (s *Store) EnsureDir() error

EnsureDir makes sure the state file directory exists.

func (*Store) Get

func (s *Store) Get(name string) (*ModelState, error)

Get returns the state for a single model, or nil if no entry exists. Read-only — does not lock.

func (*Store) IsInteractiveRunning

func (s *Store) IsInteractiveRunning(name string) bool

IsInteractiveRunning returns true when a model lock file exists and its holder PID is still alive — meaning an interactive session is in progress.

func (*Store) Load

func (s *Store) Load() (*StateFile, error)

Load returns a snapshot of the state file without taking the lock. Safe for read-only callers because writes are atomic (temp file + rename). Callers that intend to mutate and write back MUST use Update instead — otherwise two concurrent read-modify-write cycles can lose each other's changes.

func (*Store) LockModel

func (s *Store) LockModel(name string) (release func(), err error)

LockModel acquires the per-model lock so concurrent `up X` invocations don't both start the same model. Returns ErrLockHeld immediately if another live process holds the lock; stale locks (dead holder) are reclaimed transparently.

Callers must defer the returned release function.

func (*Store) PruneStale

func (s *Store) PruneStale() (changed []string, err error)

func (*Store) Put

func (s *Store) Put(ms *ModelState) error

Put atomically inserts or replaces a single model entry.

func (*Store) Remove

func (s *Store) Remove(name string) error

Remove atomically deletes a single model entry.

func (*Store) Update

func (s *Store) Update(mutate func(*StateFile) error) error

Update atomically loads the state file, applies mutate, and writes the result back while holding the state lock across the entire operation. This prevents lost updates when multiple processes touch disjoint entries concurrently (e.g. `llmconfig rm foo` racing with `llmconfig up bar`).

If mutate returns an error, the state file is left unchanged.

Jump to

Keyboard shortcuts

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