Index

RemoteLock

MMO\admin\helpers · 1 symbol · generated 5 Oct 2026

class

RemoteLock

RemoteLock.php:26

A mutual-exclusion lock held ON the target, so two people (or a person and a cron) cannot deploy to the same machine at the same time.

class MMO\admin\helpers\RemoteLock
Namespace
MMO\admin\helpers
The lock is a DIRECTORY, not a file: `mkdir` is atomic and fails when the directory already exists, on every POSIX filesystem and over NFS -- which `test -e && touch` is not. That matters here because each command is a separate ssh round-trip, so anything relying on a shell-level `flock` holding across commands would not work. Breaking a lock is atomic for the same reason. An earlier version, on finding a stale lock, simply warned and carried on -- which let two runners that both observed the same stale lock both decide they now held it, the exact situation the lock exists to prevent. Here the breaker `mv`s the directory aside and `mkdir`s a fresh one: exactly one runner can win that sequence, and the loser is told so.
$lock = new RemoteLock($runner, $target->getLockFolder()); $lock->acquire('marc@laptop deploy v4.0.21'); try {...} finally {$lock->release();}

Index

folder
owned
shell
ttl
acquire($owner, $force)Take the lock, or fail loudly.
breakLock($held)Take an existing lock away from whoever holds it, atomically.
claim($owner)Record who holds the lock, for whoever hits it next.
debugName()
getFolder()
getOwner()
isOwned()
isStale()
release()Release the lock, but only if this instance actually took it -- releasing someone else's lock would be worse than never locking at all.
__construct($shell, $folder, $ttl)

Properties4

folder

protected string $folder
Type
string

owned

protected bool $owned = false
Type
bool

shell

protected MMO\core\server\ShellRunner $shell
Type
ShellRunner

ttl

protected int $ttl
Type
int

Methods10

acquire($owner, $force)

RemoteLock.php:61

Take the lock, or fail loudly.

function acquire(string $owner, bool $force = false): void
$ownerstringa description of who is taking it, stored inside the lock for the next person.
$force = falsebooltake the lock even if someone else holds it (only ever from an explicit user request).
returnsvoid
throwsif the lock is held and is neither stale nor forced, or if breaking it was lost to a race.

breakLock($held)

RemoteLock.php:91

Take an existing lock away from whoever holds it, atomically.

protected function breakLock(string $held): void`mv` of a directory onto a new name is a single rename: exactly one of two concurrent breakers can succeed, and the `mkdir` that follows decides the winner a second time. A runner that loses either step stops rather than assuming it won.
$heldstring
returnsvoid
throwswhen another runner got there first.

claim($owner)

RemoteLock.php:105

Record who holds the lock, for whoever hits it next.

protected function claim(string $owner): void
$ownerstring
returnsvoid

isStale()

RemoteLock.php:49
function isStale(): bool
returnsboolwhether the lock exists and is older than its ttl.

release()

RemoteLock.php:115

Release the lock, but only if this instance actually took it -- releasing someone else's lock would be worse than never locking at all.

function release(): void
returnsvoid