No-Mistakes Daemon Singleton Lock Mechanism and Process Management Strategy

The no-mistakes daemon enforces a singleton instance per application home through an exclusive OS-level file lock on <NM_HOME>/daemon.lock, acquiring the lock before any IPC setup and releasing it automatically on process termination to prevent duplicate daemons.

The no-mistakes daemon ensures only one instance runs per NM_HOME directory through a robust singleton lock mechanism and comprehensive process management strategy. This design prevents race conditions and orphaned processes in concurrent environments by leveraging kernel-managed file locks that automatically release when the process exits.

How the Singleton Lock Works

The daemon implements mutual exclusion through an exclusive file lock that guarantees only one process can operate on a given application home at any time.

Cross-Platform Lock Implementation

The lock abstraction resides in internal/daemon/lock.go, with platform-specific implementations in internal/daemon/lock_unix.go and internal/daemon/lock_windows.go.

On Unix systems, the implementation uses syscall.Flock with LOCK_EX|LOCK_NB flags to attempt a non-blocking exclusive lock:

// Inside internal/daemon/lock_unix.go
func tryLockFile(f *os.File) error {
    // Non-blocking exclusive flock; returns ErrWouldBlock if another
    // process already holds the lock.
    return syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
}

On Windows, internal/daemon/lock_windows.go implements the same guarantee using CreateFile with FILE_FLAG_OVERLAPPED combined with LockFileEx for exclusive access.

Lock Acquisition Sequence

The lock acquisition occurs as the very first action in daemon.RunWithOptions, before any stale-run recovery, socket binding, or IPC setup. This ordering ensures that the daemon.lock file at <NM_HOME>/daemon.lock acts as the authoritative semaphore for daemon ownership.

If tryLockFile fails because another process holds the lock, the daemon aborts immediately with a clear error message indicating that another daemon is already running. This check happens in daemon.Start via the collision detection logic in internal/daemon/collision.go.

Process Management Strategy

The daemon's lifecycle management builds upon the singleton lock to ensure robust operation across startup, health monitoring, and shutdown phases.

Startup and Collision Detection

When daemon.Start initializes, it follows a strict sequence defined in internal/daemon/daemon.go:

  1. Acquire the lock via tryLockFile using non-blocking exclusive mode
  2. Initialize IPC by creating the Unix socket or Windows named pipe only after lock acquisition
  3. Start the RPC server to accept client connections

This sequence guarantees that no second daemon can bind to the same socket while the first daemon holds the lock. If a collision occurs, internal/daemon/collision.go logs the error and terminates the duplicate instance.

Health Monitoring and Stale Recovery

The daemon implements a health-check loop that periodically verifies daemon liveness through daemon.IsRunning. This function attempts to dial the daemon's socket with a short timeout to confirm responsiveness.

If the health check fails, indicating a dead process, the recovery mechanism in internal/daemon/recover_servers_unix.go and internal/daemon/recover_servers_windows.go detects stale lock files and removes them before allowing a new daemon to start. This prevents "zombie" locks from blocking legitimate new instances when the previous process crashed without cleaning up.

Graceful Shutdown and Signal Handling

Normal termination follows a clean shutdown sequence triggered by platform-specific signal handlers in internal/daemon/signals_unix.go and internal/daemon/signals_windows.go. These handlers translate SIGTERM, SIGINT, and other OS signals into an orderly shutdown:

// Graceful shutdown via signal handling (Unix)
func handleSignals(stop chan<- struct{}) {
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        <-sigs
        // Perform any cleanup then close the lock file
        stop <- struct{}{}
    }()
}

The shutdown sequence closes the IPC socket, releases the file lock, and removes the lock file. Because the kernel automatically releases the file lock if the process crashes or is killed, the singleton guarantee remains intact even during unexpected termination.

Summary

  • The singleton lock uses an exclusive OS-level file lock on <NM_HOME>/daemon.lock to ensure only one daemon instance runs per application home
  • Lock acquisition occurs in daemon.RunWithOptions before any socket binding or IPC initialization
  • Platform-specific implementations in internal/daemon/lock_unix.go and lock_windows.go provide cross-platform compatibility
  • Health checks via daemon.IsRunning detect stale processes and trigger recovery mechanisms in recover_servers_unix.go and recover_servers_windows.go
  • Signal handlers in signals_unix.go and signals_windows.go ensure graceful shutdown and lock release
  • The kernel automatically releases the lock on process crash, preventing permanent deadlocks

Frequently Asked Questions

How does the no-mistakes daemon prevent multiple instances from running?

The daemon uses an exclusive file lock on <NM_HOME>/daemon.lock acquired through tryLockFile at startup. If another instance holds the lock, the new instance aborts immediately with a collision error from internal/daemon/collision.go. This OS-level lock prevents race conditions between concurrent startup attempts.

What happens to the lock if the daemon process crashes?

The kernel automatically releases the file lock when the process terminates, regardless of whether the shutdown is graceful or caused by a crash. This behavior ensures that a lingering lock always reflects a live daemon, and stale locks from dead processes cannot block new instances indefinitely.

How does the daemon recover from stale lock files?

During startup, daemon.Start invokes recovery logic in internal/daemon/recover_servers_unix.go or internal/daemon/recover_servers_windows.go to detect stale locks. The daemon performs a health ping via daemon.IsRunning to verify if the locking process is alive. If the check fails, the daemon removes the stale lock file and proceeds with normal startup.

Is the singleton lock mechanism portable across operating systems?

Yes, the daemon abstracts platform differences through internal/daemon/lock.go. Unix systems use syscall.Flock with LOCK_EX|LOCK_NB, while Windows uses LockFileEx with FILE_FLAG_OVERLAPPED. Both implementations provide identical singleton guarantees, ensuring consistent behavior across Linux, macOS, and Windows environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →