268 lines
9.0 KiB
Markdown
268 lines
9.0 KiB
Markdown
# Forge Server - Redis Client Module
|
||
|
||
A high-performance arma-rs extension for Arma 3, featuring a **low-level Redis data access layer** that provides raw Redis operations as a foundation for higher-level game modules.
|
||
|
||
## 🎯 Overview
|
||
|
||
The Forge Server Redis module is designed as a **foundational data access layer** that:
|
||
- **Returns raw Redis responses** for maximum performance and flexibility
|
||
- **Serves as the foundation** for higher-level game modules (actor, garage, locker, bank, etc.)
|
||
- **Provides connection pooling** and error handling for Redis operations
|
||
- **Enables persistent data storage** across server restarts
|
||
- **Supports cross-server data sharing** in multi-server environments
|
||
|
||
## 🏗️ Layered Architecture
|
||
|
||
```
|
||
SQF Scripts
|
||
↓ (JSON responses)
|
||
Game Modules (actor, garage, locker, bank)
|
||
↓ (raw Redis responses)
|
||
Redis Client Module
|
||
↓ (Redis protocol)
|
||
Redis Server
|
||
```
|
||
|
||
**This module handles the bottom layer** - raw Redis operations with connection pooling and error handling.
|
||
|
||
## 🏗️ Internal Architecture
|
||
|
||
```
|
||
forge_server_x64.dll Extension
|
||
├── lib.rs # Core extension initialization & global runtime
|
||
├── config.example.toml # Example configuration file
|
||
└── redis/ # Redis Client module
|
||
├── mod.rs # Group definitions & module exports
|
||
├── client.rs # Connection pool management
|
||
├── config.rs # Configuration system
|
||
├── macros.rs # redis_operation! macro for boilerplate elimination
|
||
├── common.rs # String/key operations
|
||
├── hash.rs # Hash operations (HSET, HGET, etc.)
|
||
├── list.rs # List operations (LPUSH, LPOP, etc.)
|
||
└── set.rs # Set operations (SADD, SMEMBERS, etc.)
|
||
```
|
||
|
||
### Key Components
|
||
- **lib.rs**: Manages global Redis pool and single Tokio runtime
|
||
- **macros.rs**: Provides `redis_operation!` macro to eliminate boilerplate
|
||
- **Operation modules**: Focus purely on Redis logic using the macro
|
||
- **Synchronous Interface**: All functions appear synchronous to Arma while using async Redis internally
|
||
|
||
## 🚀 Features
|
||
|
||
### Raw Redis Operations
|
||
- **String Operations**: SET, GET, INCR, DECR, DEL, KEYS
|
||
- **Hash Operations**: HSET, HGET, HMSET, HGETALL, HDEL, HKEYS, HVALS, HLEN
|
||
- **List Operations**: LSET, LGET, LLEN, LRANGE, LPUSH, RPUSH, LPOP, RPOP, LTRIM, LREM
|
||
- **Set Operations**: SADD, SMEMBERS, SCARD, SREM, SISMEMBER, SPOP, SRANDMEMBER
|
||
|
||
### Performance Features
|
||
- **Connection Pooling**: bb8-redis pool with configurable size and timeouts
|
||
- **Single Runtime**: One shared Tokio runtime for all async operations
|
||
- **Macro-Based**: `redis_operation!` macro eliminates boilerplate while maintaining performance
|
||
- **Synchronous Interface**: Functions block until completion, compatible with Arma's threading model
|
||
- **Raw Responses**: Returns native Redis values for maximum performance
|
||
- **Thread Safety**: Safe concurrent access from multiple Arma threads
|
||
|
||
## ⚙️ Configuration System
|
||
|
||
Forge Server uses a TOML-based configuration system for flexible Redis connection management.
|
||
|
||
### Configuration File
|
||
|
||
Create a `config.toml` file in your extension directory:
|
||
|
||
```toml
|
||
[redis]
|
||
host = "127.0.0.1"
|
||
port = 6379
|
||
# db = 0 # Optional: Redis database number
|
||
# username = "user" # Optional: Redis username
|
||
# password = "password" # Optional: Redis password
|
||
# max_connections = 10 # Optional: Maximum connections in pool
|
||
# min_connections = 2 # Optional: Minimum idle connections in pool
|
||
# idle_timeout = 60 # Optional: Connection idle timeout (seconds)
|
||
```
|
||
|
||
### Fallback Behavior
|
||
|
||
The extension uses a robust fallback system:
|
||
1. **Loads `config.toml`** if present in the extension directory
|
||
2. **Falls back to defaults** if configuration fails or file is missing
|
||
3. **Only fails** if both config and defaults cannot establish connection
|
||
|
||
**Default Settings:**
|
||
- **Host**: `127.0.0.1`
|
||
- **Port**: `6379`
|
||
- **Max Connections**: `10`
|
||
- **Min Connections**: `2`
|
||
- **Idle Timeout**: `60 seconds`
|
||
|
||
### Common Configurations
|
||
|
||
**Development (Local Redis)**:
|
||
```toml
|
||
[redis]
|
||
host = "127.0.0.1"
|
||
port = 6379
|
||
max_connections = 5
|
||
min_connections = 1
|
||
```
|
||
|
||
**Production (Remote Redis with Authentication)**:
|
||
```toml
|
||
[redis]
|
||
host = "redis.example.com"
|
||
port = 6379
|
||
username = "arma_server"
|
||
password = "secure_password"
|
||
max_connections = 20
|
||
min_connections = 5
|
||
idle_timeout = 60
|
||
```
|
||
|
||
### Troubleshooting
|
||
|
||
**Connection Issues:**
|
||
- Verify Redis server is running: `redis-cli ping`
|
||
- Check host/port settings in `config.toml`
|
||
- Ensure firewall allows connection
|
||
|
||
**Authentication Issues:**
|
||
- Verify username/password in config
|
||
- Check Redis server auth settings
|
||
|
||
**Config File Issues:**
|
||
- Check TOML syntax with online validators
|
||
- Ensure quotes are properly closed
|
||
- Verify file permissions
|
||
|
||
**Connection Pool Benefits:**
|
||
- Pre-warmed connections for zero-latency operations
|
||
- Automatic connection recovery on network issues
|
||
- Resource-efficient connection sharing
|
||
- Configurable pool sizing for different deployment scenarios
|
||
|
||
## 🔧 Installation
|
||
|
||
1. **Prerequisites**:
|
||
- Redis server (local or remote)
|
||
- Arma 3 server with extension support
|
||
|
||
2. **Extension Setup**:
|
||
- Build the extension: `cargo build --release`
|
||
- Copy the compiled `forge_server_x64.dll` to your Arma 3 server
|
||
- Copy `config.example.toml` to `config.toml` and configure as needed
|
||
- Load in server config or mission
|
||
|
||
3. **Redis Server**:
|
||
```bash
|
||
# Start Redis server
|
||
redis-server
|
||
|
||
# Verify connection
|
||
redis-cli ping
|
||
```
|
||
|
||
## 📝 Documentation
|
||
|
||
- **[API Reference](./api-reference.md)** - Complete Redis command reference
|
||
- **[Usage Examples](./usage-examples.md)** - Practical SQF integration examples
|
||
|
||
## 📊 Performance
|
||
|
||
- **Connection Pool**: 2-10 persistent connections using bb8-redis
|
||
- **Single Runtime**: One shared Tokio runtime eliminates overhead from multiple runtimes
|
||
- **Macro Efficiency**: Zero-cost abstraction – macros expand to optimal code at compile time
|
||
- **Synchronous Blocking**: Functions use `block_on()` for Arma compatibility without sacrificing async I/O benefits
|
||
- **Response Format**: Raw Redis responses for minimal overhead
|
||
- **Thread Safety**: Multiple Arma threads can safely call operations concurrently
|
||
- **Memory Efficient**: Minimal resource usage per operation
|
||
|
||
## 🔄 Response Format
|
||
|
||
This module returns **raw Redis responses** as strings for maximum performance:
|
||
|
||
### Success Responses
|
||
- **String values**: `"John"` (raw string)
|
||
- **Numbers**: `"42"` (number as string)
|
||
- **Lists/Arrays**: `"item1,item2,item3"` (comma-separated)
|
||
- **Hashes**: `"key1,value1,key2,value2"` (comma-separated key-value pairs)
|
||
- **Boolean**: `"1"` or `"0"` (for exists checks)
|
||
- **Status**: `"OK"` (for successful SET operations)
|
||
|
||
### Error Responses
|
||
- **Format**: `"Error: <error description>"`
|
||
- **Pool errors**: `"Error: Redis pool not initialized"`
|
||
- **Connection errors**: `"Error: <connection error>"`
|
||
- **Redis errors**: `"Error: <Redis operation error>"`
|
||
|
||
### Higher-Level JSON Formatting
|
||
Game modules (actor, garage, etc.) will wrap these raw responses in structured JSON for SQF consumption.
|
||
|
||
## ⚙️ Macro-Based Implementation
|
||
|
||
This extension uses a **macro-based architecture** to eliminate boilerplate while maintaining performance:
|
||
|
||
### The `redis_operation!` Macro
|
||
|
||
```rust
|
||
pub fn set_key(key: String, value: String) -> String {
|
||
redis_operation!(conn => {
|
||
match conn.set::<_, _, ()>(&key, &value).await {
|
||
Ok(()) => "OK".to_string(),
|
||
Err(e) => format!("Error: {}", e),
|
||
}
|
||
})
|
||
}
|
||
```
|
||
|
||
### What the Macro Handles
|
||
|
||
- **Pool Management**: Retrieves Redis connection pool
|
||
- **Error Handling**: Returns "Error: ..." for pool/connection failures
|
||
- **Async Bridging**: Uses shared Tokio runtime via `block_on()`
|
||
- **Connection Acquisition**: Gets connection from pool with error handling
|
||
- **Cleanup**: Automatic connection return to pool
|
||
|
||
### Benefits
|
||
|
||
- **Reduced Code**: 70% less boilerplate per function
|
||
- **Consistency**: Identical error handling across all operations
|
||
- **Maintainability**: Changes to connection logic in one place
|
||
- **Performance**: No runtime overhead from abstraction
|
||
- **Synchronous Interface**: Functions block until Redis operation completes
|
||
|
||
## 🛠️ Development
|
||
|
||
- **Language**: Rust (Edition 2024)
|
||
- **Dependencies**: arma-rs, bb8-redis, redis, tokio
|
||
- **Architecture**: Macro-based design with single runtime and connection pool
|
||
- **Key Patterns**:
|
||
- Global state management in `lib.rs`
|
||
- Boilerplate elimination via `redis_operation!` macro
|
||
- Synchronous interfaces over async operations
|
||
- Raw Redis responses for minimal overhead
|
||
- **Testing**: Unit tests for core functionality
|
||
|
||
|
||
## 🚨 Error Handling
|
||
|
||
The extension provides comprehensive error handling:
|
||
- Connection failures
|
||
- Redis operation errors
|
||
- Invalid parameters
|
||
- Pool initialization errors
|
||
|
||
All errors include descriptive messages for debugging.
|
||
|
||
## 🔍 Monitoring
|
||
|
||
Connection pool status and Redis operations can be monitored through:
|
||
- Extension logs
|
||
- Redis server logs
|
||
- Connection pool metrics
|
||
|
||
---
|
||
|
||
**Built with ❤️ for the Arma 3 community** |