Documentation ¶
Overview ¶
Package lock provides a lock object to synchronize access to a directory among multiple processes.
The implementation relies on lock files written inside the locked directory.
To safely handle situations where a process holding the lock exits without releasing the lock, the implementation employs a multi-level locking strategy: lock level 0 is considered the master lock. If the master lock is found to be stale (the owning process is dead), the process seeking the lock will need to grab lock level 1 before it can re-claim lock level 0 (only one process can do so, ensuring only one process proceeds to own lock level 0).
If in turn lock level 1 is found to be stale, the process will need to grab lock level 2, and so on. Eventually, the process seeking the lock will reach a level N where the lock is not stale: if the level N lock is available, the process grabs it, reclaims lock level 0 for itself (after checking it's allowed to), and removes all locks for levels > 0.
If the level N lock is held by another process, the process seeking the lock will retry starting at level 0.
Lock level 0 determines who holds the lock once TryLock returns. Higher level locks are only held while TryLock is running, and are ephemeral. This scheme ensures that exactly one process ever grabs the lock regardless of whether it's stale.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type TryLocker ¶
type TryLocker interface { sync.Locker // TryLock attempts to grab the lock, but does not hang if the lock is // actively held by another process. Instead, it returns false. TryLock() bool }
TryLocker is a sync.Locker augmented with TryLock.
type TryLockerSafe ¶
type TryLockerSafe interface { // TryLock attempts to grab the lock, but does not hang if the lock is // actively held by another process. Instead, it returns false. TryLock() (bool, error) // Lock blocks until it's able to grab the lock. Lock() error // Unlock releases the lock. Should only be called when the lock is // held. Unlock() error // Must returns a TryLocker whose Lock, TryLock and Unlock methods // panic rather than return errors. Must() TryLocker }
TryLockerSafe is like TryLocker, but the methods can return an error and never panic.
func NewDirLock ¶
func NewDirLock(dir string) TryLockerSafe
NewDirLock creates a new TryLockerSafe that can be used to manipulate a file lock for a directory.