Fix bd-54: Prevent multiple daemon instances via file locking

- Implemented daemon.lock using flock (Unix) and LockFileEx (Windows)
- Lock acquired before PID file, held for daemon lifetime
- Eliminates race conditions in concurrent daemon starts
- Backward compatible: falls back to PID check for old daemons
- Updated isDaemonRunning() to check lock availability
- All tests pass including new lock and backward compatibility tests

Amp-Thread-ID: https://ampcode.com/threads/T-0e2627f4-03f9-4024-bb4b-21d23d296300
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-22 13:59:21 -07:00
parent d1d3fcdf02
commit e291f464ee
9 changed files with 475 additions and 76 deletions
+13
View File
@@ -754,6 +754,8 @@ Issue is "ready" if status is `open` and it has no open `blocks` dependencies.
beads/
├── cmd/bd/ # CLI entry point
│ ├── main.go # Core commands (create, list, show, update, close)
│ ├── daemon.go # Background daemon for auto-sync
│ ├── daemon_lock.go # Daemon exclusivity enforcement
│ ├── init.go # Project initialization
│ ├── quickstart.go # Interactive guide
│ └── ...
@@ -764,6 +766,17 @@ beads/
└── EXTENDING.md # Database extension guide
```
### Daemon Locking
bd ensures only one daemon runs per repository using file locking:
- **Lock file**: `.beads/daemon.lock` holds an exclusive file lock (via `flock` on Unix, `LockFileEx` on Windows)
- **Process-level exclusivity**: The lock is held by the daemon process for its entire lifetime
- **Automatic cleanup**: Lock is automatically released when daemon exits (via file descriptor close)
- **Race condition prevention**: Multiple simultaneous daemon starts are safely serialized by the lock
The lock file is the single source of truth for daemon status. Commands like `bd daemon --status` check lock availability rather than PID file contents, eliminating race conditions where multiple daemons could start simultaneously.
## Extending bd
Applications can extend bd's SQLite database with their own tables. See [EXTENDING.md](EXTENDING.md) for the full guide.