# Global Lock System Documentation

## Overview

The global lock system provides cross-process synchronization using file-system based locking. This ensures that when one program is accessing a shared resource (like a database), other programs must wait until the lock is released.

The system has been refactored into a separate `lock.lua` module for better maintainability and cross-platform compatibility.

## Files Modified/Created

### `/Volumes/nc/nc-server/lib/db/lock.lua`

Main lock implementation with cross-platform support:

**Core Functions:**

- **`lock.waitForGlobalLock(lockName, timeout)`** - Acquire a global lock
- **`lock.releaseGlobalLock(lockName, showError)`** - Release a global lock
- **`lock.releaseAllGlobalLocks()`** - Release all locks held by this process
- **`lock.getProcessId()`** - Get current process ID (cross-platform)
- **`lock.isLockHeld(lockName)`** - Check if lock is held by this process
- **`lock.getLockInfo(lockName)`** - Get lock information
- **`lock.getHeldLocks()`** - Get list of all held locks
- **`lock.cleanupStaleLocks()`** - Clean up stale locks from dead processes
- **`lock.setDebugLevel(level)`** - Set debug logging level (0=none, 1=basic, 2=verbose)

**Cross-Platform Features:**

- **Windows**: Uses `tasklist` for process detection and `ping` for delays
- **macOS/Linux**: Uses `kill -0` for process detection and `sleep` for delays
- **Process ID Detection**: Handles different methods across platforms
- **File Locking**: Uses atomic file operations for race condition prevention

### `/Volumes/nc/nc-server/test/lib/lock-test.lua`

Comprehensive test suite based on dt-test.lua template:

**Test Categories:**

- **Basic Functionality**: Lock/unlock, double locking, multiple locks
- **Timeout Handling**: Proper timeout behavior and timing
- **Cross-Process Tests**: Subprocess spawning and contention testing
- **Stale Lock Cleanup**: Dead process detection and cleanup
- **Platform-Specific**: Tests for Windows vs Unix-like systems

**Multi-Process Testing:**

- Creates temporary Lua scripts for subprocess testing
- Tests lock contention between separate processes
- Verifies proper cleanup when processes exit
- Platform-specific subprocess execution

## How It Works

1. **Lock Files**: Each lock creates a file in `preference/lock/` directory containing the process ID
2. **Stale Lock Detection**: Before waiting, checks if the holding process is still alive using `kill -0 <pid>`
3. **Cross-Process**: Multiple separate programs can synchronize access to shared resources
4. **Timeout Protection**: Prevents infinite waiting with configurable timeouts
5. **Automatic Cleanup**: Dead process locks are automatically detected and removed

## Usage Examples

### Basic Usage

```lua
local lock = require "db/lock"
-- Acquire a global lock
local success = lock.waitForGlobalLock("database-access", 30)
if success then
    -- Do work with shared resource
    print("Working with database...")
    -- Release the lock
    lock.releaseGlobalLock("database-access")
else
    print("Failed to acquire lock - timeout")
end
```

### Through Coro Module (for existing coroutine code)

```lua
local coro = require "coro"
-- Acquire a global lock
local sock = getCurrentSocket() -- your socket object
local success = coro.waitForLock(sock, "database-access", 30)
if success then
    -- Do work with shared resource
    print("Working with database...")
    -- Release the lock
    coro.releaseLock("database-access")
else
    print("Failed to acquire lock - timeout")
end
```

## Benefits

1. **Cross-Process Synchronization**: Multiple programs can coordinate access
2. **Deadlock Prevention**: Timeout mechanisms prevent infinite waiting
3. **Automatic Cleanup**: Stale locks from crashed processes are automatically removed
4. **Debug Support**: Comprehensive logging when debug level > 0
5. **Coroutine Integration**: Works seamlessly with existing coroutine yield system
6. **Cross-Platform**: Works on macOS, Windows, and Linux

## Testing

To run the test:

```bash
cd /Volumes/nc/nc-server/test
lj lib/lock-test.lua
```
