v0.3.0 storage with sqlite3 and pid management added

This commit is contained in:
2025-10-30 09:52:23 -04:00
parent 0ad608293e
commit b79900b1bf
18 changed files with 1570 additions and 69 deletions

View File

@ -6,6 +6,25 @@ Content-Type: `application/json` (required for POST/PUT)
## Endpoints
### Health Check
`GET /health`
Returns server status.
**Response (200):**
```json
{
"status": "healthy",
"time": 1699123456,
"storage": "ok"
}
```
Storage states:
- `"disabled"` - No storage path configured
- `"ok"` - Database operational
- `"degraded"` - Write failures detected, operating memory-only
### Create Game
`POST /games`
@ -29,8 +48,8 @@ Creates new game with specified players.
```
- `type` (integer, required): 1=human, 2=computer
- `level` (integer, 0-20): AI skill level for computer players
- `searchTime` (integer, 100-10000ms): AI thinking time for computer players
- `level` (integer, 0-20): Engine skill level for computer players
- `searchTime` (integer, 100-10000ms): Engine thinking time for computer players
- `fen` (string): Starting position in FEN notation (default: standard position)
**Response (201):**

View File

@ -9,13 +9,17 @@ Fiber web server handling HTTP requests/responses. Implements routing, rate limi
Central command handler containing business logic. Single `Execute(Command)` entry point decouples transport from logic. Uses synchronous UCI engine for validation, asynchronous EngineQueue for computer moves.
### Service Layer (`internal/service`)
In-memory state storage without chess logic. Thread-safe game map protected by RWMutex. Manages game lifecycle, snapshots, and player configuration.
In-memory state storage without chess logic. Thread-safe game map protected by RWMutex. Manages game lifecycle, snapshots, and player configuration. Coordinates with storage layer for optional persistence.
### Storage Layer (`internal/storage`)
Optional SQLite persistence with async write pattern. Buffered channel (1000 ops) processes writes sequentially in background. Graceful degradation on write failures. WAL mode for development environments.
### Supporting Modules
- **Engine** (`internal/engine`): UCI protocol wrapper for Stockfish process communication
- **Game** (`internal/game`): Game state with snapshot history
- **Board** (`internal/board`): FEN parsing and ASCII generation
- **Core** (`internal/core`): Shared types, API models, error constants
- **CLI** (`cmd/chessd/cli`): Database management commands
## Request Flow
@ -35,12 +39,28 @@ In-memory state storage without chess logic. Thread-safe game map protected by R
5. Callback updates game state via service
6. Client polls for completion
## Persistence Flow
### Write Operations
1. Service layer calls storage method (RecordNewGame, RecordMove, DeleteUndoneMoves)
2. Operation queued to buffered channel (non-blocking)
3. Writer goroutine processes queue sequentially
4. Transactions ensure atomicity
5. Failures trigger degradation to memory-only mode
### Query Operations
1. CLI invokes Store.QueryGames with filters
2. Direct database read (no queue)
3. Results formatted as tabular output
## Concurrency
- **HTTP Server**: Fiber handles concurrent connections
- **Game State**: Single RWMutex protects game map (concurrent reads, serial writes)
- **Engine Workers**: Fixed pool (2 workers) with dedicated Stockfish processes
- **Validation Engine**: Single mutex-protected instance for synchronous validation
- **Storage Writer**: Single goroutine processes write queue sequentially
- **PID Lock**: File-based exclusive lock prevents multiple instances
## Data Structures
@ -58,4 +78,32 @@ type Snapshot struct {
Commands encapsulate operations with type and arguments, processed by single Execute method.
### Player Configuration
Players identified by UUID, configured with type (human/computer), skill level, and search time.
Players identified by UUID, configured with type (human/computer), skill level, and search time.
### Storage Schema
```sql
games (
game_id TEXT PRIMARY KEY,
initial_fen TEXT,
white_player_id TEXT,
white_type INTEGER,
white_level INTEGER,
white_search_time INTEGER,
black_player_id TEXT,
black_type INTEGER,
black_level INTEGER,
black_search_time INTEGER,
start_time_utc DATETIME
)
moves (
move_id INTEGER PRIMARY KEY,
game_id TEXT,
move_number INTEGER,
move_uci TEXT,
fen_after_move TEXT,
player_color TEXT,
move_time_utc DATETIME,
FOREIGN KEY (game_id) REFERENCES games(game_id)
)
```

View File

@ -21,21 +21,49 @@ go build ./cmd/chessd
- `-host`: Server host (default: localhost)
- `-port`: Server port (default: 8080)
- `-dev`: Development mode with relaxed rate limits
- `-storage-path`: SQLite database file path (enables persistence)
- `-pid`: PID file path for process tracking
- `-pid-lock`: Enable exclusive locking (requires -pid)
### Modes
```bash
# Production (1 req/s rate limit)
# In-memory only
./chessd
# Development (10 req/s rate limit)
./chessd -dev
# With persistence
./chessd -storage-path ./db/chess.db
# Singleton enforcement (requires same PID file path across instances)
./chessd -pid /var/run/chessd.pid -pid-lock
# Development with all features
./chessd -dev -storage-path chess.db -pid /tmp/chessd.pid
```
## Database Management
### CLI Commands
```bash
# Initialize database schema
./chessd db init -path chess.db
# Query games
./chessd db query -path chess.db [-gameId ID] [-playerId ID]
# Delete database
./chessd db delete -path chess.db
```
Query parameters accept `*` for all records (default if omitted) or specific IDs for filtering.
## Project Structure
```
chess/
├── cmd/chessd/ # Entry point
├── cmd/chessd/
│ ├── main.go # Entry point
│ ├── pid.go # PID file management
│ └── cli/ # Database CLI
├── internal/
│ ├── board/ # FEN/ASCII operations
│ ├── core/ # Shared types
@ -43,28 +71,14 @@ chess/
│ ├── game/ # Game state
│ ├── http/ # Fiber handlers
│ ├── processor/ # Command processing
── service/ # State management
── service/ # State management
│ └── storage/ # SQLite persistence
└── test/ # Test scripts
```
## Testing
```bash
# Unit tests
go test ./...
# API tests (requires dev mode)
./chessd -dev &
./test/test-api.sh
```
Test script validates:
- Basic CRUD operations
- Computer move triggering ("cccc" mechanism)
- Pending state protection
- Rate limiting
- Input validation
- Error handling
See [test documentation](../test/README.md) for details.
## Configuration
@ -73,6 +87,20 @@ Test script validates:
- Worker count: 2 (internal/processor/processor.go)
- Queue capacity: 100 (internal/processor/queue.go)
- Min search time: 100ms (internal/processor/processor.go)
- Write queue: 1000 operations (internal/storage/storage.go)
- DB connections: 25 max, 5 idle (internal/storage/storage.go)
### Storage Configuration
- WAL mode enabled in development for concurrency
- Foreign key constraints enforced
- Async write pattern with 2-second drain on shutdown
- Degradation to memory-only on write failures
### PID Management
- Singleton enforcement requires same PID file path - all instances must use the same -pid value
- Stale PID detection via signal 0 checking
- Exclusive file locking with LOCK_EX|LOCK_NB
- Automatic cleanup on graceful shutdown
### Validation Rules
- Player type: 1 (human) or 2 (computer)