Documentation
¶
Overview ¶
Package lock is the spec fabric slice for advisory file locking — a host primitive a plugin physically cannot hold (a syscall.Flock over an on-disk lock file). RELOCATED from sdk/kit (#55 fabric-primitive extraction). It carries the heavy syscall dependency in its OWN slice (Rule 2: minimal imports) so a consumer that needs a lock never drags anything else, and a consumer that needs nothing else never drags syscall. charly core inlines from here; sdk/kit re-exports the same symbols so the compiled-in candy/plugin-preempt and other plugin call sites are untouched.
Index ¶
- Variables
- func AcquireFileLock(path string, blocking bool) (release func() error, err error)
- func AcquireImageBuildLock(fullTag string) (func() error, error)
- func AcquireLocalPkgBuildLock(srcDir string) (func() error, error)
- func AcquireVmDomainLock(domain string) (func() error, error)
- func BedVmDomains(name string, node spec.BundleNode) []string
- func ImageBuildLockPath(fullTag string) (string, error)
- func InstallDirAtomic(tmp, final string) error
Constants ¶
This section is empty.
Variables ¶
var ErrLockBusy = errors.New("file lock held by another process")
ErrLockBusy is returned by a NON-blocking AcquireFileLock when another holder already owns the lock. Callers detect it with errors.Is to render a precise "already in progress" message.
Functions ¶
func AcquireFileLock ¶
AcquireFileLock takes an advisory flock on path (creating the file + parent dirs on demand) and returns a release closure that unlocks + closes.
blocking selects the contention behavior:
- true → LOCK_EX: wait until the lock is free (serialize, never fail).
- false → LOCK_EX|LOCK_NB: return ErrLockBusy immediately when another holder exists.
The lock file is deliberately NOT unlinked on release (unlinking a held lock races a waiter that already opened the prior inode). flock is per-open-file-description, so two acquires of the same path — even within ONE process — contend, which the duplicate-run guard relies on.
func AcquireImageBuildLock ¶
AcquireImageBuildLock takes the blocking per-image build lock for fullTag.
func AcquireLocalPkgBuildLock ¶
AcquireLocalPkgBuildLock serializes concurrent localpkg builds sharing a source dir.
func AcquireVmDomainLock ¶
AcquireVmDomainLock takes a BLOCKING, host-global advisory lock serializing every check bed that occupies the given libvirt domain. Host-global (under ~/.cache/charly/.locks/) because the qemu:///session domain namespace is host-wide, shared across project dirs.
func BedVmDomains ¶
func BedVmDomains(name string, node spec.BundleNode) []string
BedVmDomains returns the sorted, deduped libvirt domain names (charly-<from>) a bed's VM(s) occupy — the bed's own vm target plus any group-member vm targets. This is the unit of exclusive host contention two DISTINCT beds can collide on (the per-domain lock in AcquireVmDomainLock serializes them).
func ImageBuildLockPath ¶
ImageBuildLockPath is the pure per-image build-lock key derivation: the user-cache lock file for an image ref, with the :tag stripped (preserving any registry:port colon) so every CalVer build of one image shares ONE lock — a shared intermediate built COLD once while distinct leaves fan out in parallel. Shared across the module boundary (R3) so charly core's acquireImageBuildLock AND the compiled-in candy/plugin-build DRIVE derive the byte-identical path.
func InstallDirAtomic ¶
InstallDirAtomic atomically installs the freshly-populated tmp directory as final. When final already exists, the two dirs are swapped in a single atomic renameat2(RENAME_EXCHANGE) — a concurrent reader of final always sees a complete dir (the old one before, the new one after) — and the swapped-out old content (now under tmp) is removed. When final is absent, a plain rename installs it. A lost create-race (a concurrent process installed identical content first) is benign: the redundant tmp is discarded. Linux-only (renameat2); the project targets Linux. Relocated from charly core (P8b) so the build render engine and charly's staging primitives share the one primitive.
Types ¶
This section is empty.