stacklock

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MPL-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultTimeout = 5 * time.Minute

DefaultTimeout is a suggested wait duration for callers that want to opt into waiting on a contended lock (e.g. via --lock-timeout) rather than the fail-immediately default. It is no longer applied automatically: a caller-supplied timeout of 0 means "fail immediately," matching terraform's own -lock-timeout=0 default, rather than silently blocking for minutes with no output.

Functions

func With

func With(ctx context.Context, rt *runtime.Runtime, operation string, timeout time.Duration, fn func() error) error

With acquires an exclusive stack lock against the runtime's context and runs fn while holding it. The lock is released on return — including on panic — via deferred Release. operation labels what the caller is doing ("up", "apply", "destroy", "bootstrap", "plan") so concurrent operators see the holder's intent in busy-error messages. timeout is how long to wait on contention before failing; 0 fails immediately (matching terraform's own -lock-timeout=0 default) rather than blocking silently.

Types

type LockBusyError

type LockBusyError struct {
	Path   string
	Holder *LockInfo
}

LockBusyError is returned by Acquire when the timeout elapses with the lock still held. Holder is best-effort and may be nil when the lock-file body is absent or unparseable.

func (*LockBusyError) Error

func (e *LockBusyError) Error() string

Error renders a human-readable description of the lock contention; the Holder fields are included when known so operators can identify the blocker without opening the file.

type LockInfo

type LockInfo struct {
	ID        string    `json:"id"`
	Operation string    `json:"operation"`
	Mode      Mode      `json:"mode"`
	Who       string    `json:"who"`
	Version   string    `json:"version"`
	ProjectID string    `json:"project_id"`
	Context   string    `json:"context"`
	Created   time.Time `json:"created"`
	PID       int       `json:"pid"`
}

LockInfo records who holds a stack lock and why. Persisted into a sidecar file next to the lock so a blocked contender can name the holder in its busy error and operators can identify the holding process.

func NewInfo

func NewInfo(rt *runtime.Runtime, operation string) LockInfo

NewInfo constructs the LockInfo persisted into the holder-info sidecar for a given runtime and operation label. The result is diagnostic only — Acquire writes it next to the lock so the next contender's busy error can name the holder and the holding PID.

type Mode

type Mode int

Mode distinguishes writer (Exclusive) from reader (Shared) acquisition. Only Exclusive is supported today; Shared is reserved for read-only plan operations (§7.3 of the terraform-lifecycle-hardening spike).

const (
	Exclusive Mode = iota
	Shared
)

type Release

type Release func() error

Release frees a previously-acquired lock. Implementations must be idempotent: calls after the first one return nil.

type StackLock

type StackLock interface {
	Acquire(ctx context.Context, info LockInfo, timeout time.Duration) (Release, error)
	Inspect(ctx context.Context) (*LockInfo, error)
	ForceRelease(ctx context.Context, lockID string, reason string) error
}

StackLock coordinates exclusive access to a single (projectRoot, contextName) tuple across windsor invocations. A given StackLock instance is constructed per operation; implementations are not required to be safe for concurrent in-process reuse of one instance.

func ForRuntime

func ForRuntime(rt *runtime.Runtime) (StackLock, error)

ForRuntime returns the StackLock for the runtime's context — the same lock that With acquires. It is exposed so operator-facing recovery (windsor unlock) can inspect and force-release a stuck lock without duplicating the path derivation. Returns an error when the runtime is nil or has not been configured yet (empty scratch path).

func NewLocalFlockLock

func NewLocalFlockLock(lockPath string) StackLock

NewLocalFlockLock returns a StackLock backed by a local advisory file lock at lockPath. The lock file's parent directory is created on first Acquire. Single-host coverage only; network filesystems where flock semantics are unreliable (NFS) will degrade silently.

Jump to

Keyboard shortcuts

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