Help us shape the future of Go! Take the 2026 Go Developer Survey

locks

package
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package locks wraps gofrs/flock with typed-reason acquire helpers for the kernel-managed advisory locks required by and 440b, plus a non-blocking single-attempt try (TryAcquire) for the retention pruner.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type LockReason

type LockReason string

LockReason classifies the outcome of an acquire attempt, in the vocabulary shares with. ReasonNone covers a successful acquire.

const (
	ReasonNone             LockReason = "none"
	ReasonLockTimeout      LockReason = "lock_timeout"
	ReasonLockContended    LockReason = "lock_contended"
	ReasonLockAcquireError LockReason = "lock_acquire_error"
)

func Acquire

func Acquire(path string, timeout time.Duration) (release func(), reason LockReason, err error)

Acquire takes an exclusive advisory lock on path with the given acquisition timeout. Production callers (step (1) and 440b) pass 2*time.Second; tests may pass a shorter duration.

On success, release closes the underlying lock object — which unlocks the file and closes the file descriptor — and reason is ReasonNone. On timeout, reason is ReasonLockTimeout and err is the context deadline error. On any other lock-syscall failure, reason is ReasonLockAcquireError and err is the underlying error so callers can map it to the error-category vocabulary.

This helper locks exactly the path it is given and does not own the data file. Callers pass a dedicated sidecar lock path (`<settings>.lock`, `<session>.json.lock`) that is never the target of an atomic rename, per step (1) — locking the renamed-over data file would not provide cross-process mutual exclusion. If the lock file does not exist, gofrs/flock creates it at mode 0600 before attempting the lock.

func AcquireAt

func AcquireAt(dir *os.File, name string, timeout time.Duration) (release func(), reason LockReason, err error)

AcquireAt takes the same kernel flock as Acquire, so the two exclude each other on one sidecar.

func TryAcquire

func TryAcquire(path string) (release func(), reason LockReason, err error)

TryAcquire makes exactly one non-blocking attempt to take an exclusive advisory lock on path and returns immediately — there is no wait, retry, or timeout. The retention pruner uses it to probe a session's resume lock before deleting the file: a single try with "no wait timeout applies."

On success, release closes the underlying lock object (unlock + close fd) and reason is ReasonNone. When another holder currently owns the lock, release is nil, reason is ReasonLockContended, and err is nil — a non-error skip path the pruner must distinguish from a real failure so it can leave the live session alone silently. On a lock-syscall/construction failure, release is nil, reason is ReasonLockAcquireError, and err is the underlying error.

Unlike Acquire(path, 0), this actually attempts the lock: Acquire with a zero timeout hands gofrs/flock an already-expired context, so TryLockContext reports a timeout without ever calling the lock syscall. TryAcquire calls the single-attempt TryLock directly instead. The same sidecar-path contract as Acquire applies: callers pass a dedicated lock path, never an atomically renamed-over data file.

Jump to

Keyboard shortcuts

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