docs/stale-lock-recovery.md
When build processes are killed (Ctrl+C, task manager, etc.), lock files can be left behind without PID metadata. This happens when a process:
.lock).lock.pid)Previous behavior: Age-based fallback only triggered after 30 minutes, causing long build delays.
# Old threshold
if age_seconds > 1800: # 30 minutes
# New threshold
if age_seconds > 120: # 2 minutes
# Check for stale lock BEFORE attempting acquisition
if self.lock_file.exists():
if self._check_stale_lock():
print(f"Removed stale lock before acquisition: {self.lock_file}")
Lock state is stored in a centralized SQLite database (.cache/locks.db or ~/.fastled/locks.db).
Each lock record contains: lock name, owner PID, lock mode (read/write), operation, hostname, timestamp.
os.kill(pid, 0) on UnixOpenProcess() on WindowsTest script demonstrates two scenarios:
uv run python test_stale_lock.py
Test 1: Stale lock (3 minutes old, no metadata)
Test 2: Recent lock (30 seconds old, no metadata)
Before fix:
bash test
# Blocks for up to 30 minutes on stale lock
# User has to manually kill processes or delete lock files
After fix:
bash test
# Detects stale lock immediately
# Removes it automatically
# Build proceeds in <0.1s
# Output:
# Detected stale lock at .build/locks/libfastled_build.lock (process dead)
# Removed stale lock file: .build/locks/libfastled_build.lock
Possible enhancements (not currently implemented):