v0.3.0 storage with sqlite3 and pid management added
This commit is contained in:
23
doc/api.md
23
doc/api.md
@ -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):**
|
||||
|
||||
@ -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)
|
||||
)
|
||||
```
|
||||
@ -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)
|
||||
|
||||
Reference in New Issue
Block a user