lock

package
v0.10.3 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package lock implements a cross-process file lock using an exclusive PID file, ported from FileLock in src/utils.ts of github.com/colbymchenry/codegraph (MIT).

Protocol: the lock file is created with O_CREATE|O_EXCL so only one process can win the race. On conflict the holder's PID and the file mtime are read: the lock is considered STALE (deleted and retaken) if the mtime is older than 2 minutes OR the PID is no longer alive (signal 0 probe). Otherwise ErrLockUnavailable is returned.

Release verifies the stored PID matches our own before unlinking, so a late-running stale-cleanup by another process cannot accidentally release a lock we legitimately hold.

All external dependencies (clock, own PID, alive-probe) are injectable for deterministic unit tests.

Index

Constants

View Source
const StaleTimeout = 2 * time.Minute

StaleTimeout is how old a lock file's mtime must be before it is considered stale regardless of PID liveness, matching the original's STALE_TIMEOUT_MS = 2 minutes.

Variables

View Source
var ErrLockUnavailable = errors.New("codegraph database is locked by another process")

ErrLockUnavailable is returned when the lock is held by another live process that has not timed out. Callers (e.g. the file watcher) can use errors.Is to distinguish this from unexpected I/O errors.

Functions

This section is empty.

Types

type AliveFunc

type AliveFunc func(pid int) bool

AliveFunc probes whether a process is alive. The production value sends signal 0 (os.FindProcess + p.Signal(syscall.Signal(0))).

type FileLock

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

FileLock is a cross-process exclusive lock backed by a PID file. The zero value is not usable; construct with New.

func New

func New(path string, opts ...Option) *FileLock

New returns a FileLock for the given path, configured by opts.

func (*FileLock) Acquire

func (fl *FileLock) Acquire() error

Acquire attempts to take the lock. It returns ErrLockUnavailable (wrapped) when another live, non-timed-out process holds it, and other errors for unexpected I/O failures.

func (*FileLock) IsHeld

func (fl *FileLock) IsHeld() bool

IsHeld reports whether this instance currently holds the lock.

func (*FileLock) Release

func (fl *FileLock) Release()

Release releases the lock. It verifies that the stored PID equals our own before unlinking, so a concurrent stale-cleanup cannot disrupt us. Safe to call when the lock is not held (no-op).

func (*FileLock) WithLock

func (fl *FileLock) WithLock(fn func() error) error

WithLock acquires the lock, calls fn, then releases. The lock is released even if fn panics.

type NowFunc

type NowFunc func() time.Time

NowFunc returns the current wall-clock time. Injectable so tests can control time without sleeping.

type Option

type Option func(*FileLock)

Option configures a FileLock.

func WithAliveProbe

func WithAliveProbe(fn AliveFunc) Option

WithAliveProbe overrides the alive-probe function. Defaults to a signal-0 probe via os.FindProcess.

func WithClock

func WithClock(fn NowFunc) Option

WithClock overrides the clock used for stale-timeout checks. Useful in tests to advance time without sleeping.

func WithPID

func WithPID(pid int) Option

WithPID overrides the PID written to the lock file and used for ownership checks. Defaults to os.Getpid().

Jump to

Keyboard shortcuts

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