- Add separate momentry_playground binary with distinct configuration - Production (momentry): Port 3002, Redis prefix 'momentry:' - Development (momentry_playground): Port 3003, Redis prefix 'momentry_dev:' - Add SERVER_PORT and REDIS_KEY_PREFIX config via environment variables - Replace all hardcoded Redis key prefixes with configurable values - Create .env.development for playground environment settings - Update .env with production defaults - Add dotenv dependency for environment file loading Configuration isolation allows running both binaries simultaneously without port conflicts or Redis key collisions.
8.7 KiB
8.7 KiB
Playground Binary Implementation Plan
Overview
Create separate momentry_playground binary with distinct configuration from momentry (production).
| Aspect | Production (momentry) |
Development (momentry_playground) |
|---|---|---|
| Port | 3002 | 3003 |
| Redis Prefix | momentry: |
momentry_dev: |
| Worker | Enabled | Disabled |
| Purpose | Production deployment | Testing/Development |
Files to Modify
Files Changed: 6 files (+1 new)
├── src/core/config.rs ← Add server_port(), redis_key_prefix()
├── src/core/db/redis_client.rs ← Replace hardcoded prefixes
├── src/core/cache/redis_cache.rs ← Use configurable prefix
├── src/main.rs ← Update CLI defaults
├── src/playground.rs ← NEW: Development binary
├── Cargo.toml ← Add new binary
└── .env.development ← NEW: Dev environment config
Implementation Steps
Step 1: Update src/core/config.rs
Add after line 51 (after MEDIA_BASE_URL):
pub static SERVER_PORT: Lazy<u16> = Lazy::new(|| {
env::var("MOMENTRY_SERVER_PORT")
.unwrap_or_else(|_| "3002".to_string())
.parse()
.unwrap_or(3002)
});
pub static REDIS_KEY_PREFIX: Lazy<String> = Lazy::new(|| {
env::var("MOMENTRY_REDIS_PREFIX")
.unwrap_or_else(|_| "momentry:".to_string())
});
Step 2: Update src/core/db/redis_client.rs
Replace all hardcoded momentry: prefixes with configurable prefix.
Import at top:
use crate::core::config::REDIS_KEY_PREFIX;
Pattern for each method:
let prefix = REDIS_KEY_PREFIX.as_str();
let key = format!("{}job:{}", prefix, uuid);
Affected lines:
| Line | Key Pattern |
|---|---|
| 47 | job:{uuid} |
| 81, 109 | job:{uuid}:processor:{processor} |
| 136, 146 | progress:{uuid} |
| 172 | jobs:active |
| 179 | jobs:active → jobs:completed |
| 187 | jobs:active → jobs:failed |
| 194 | jobs:active |
| 201, 208 | health:momentry_core |
| 214 | monitor:job:{uuid} |
| 242, 300 | errors:{uuid} |
| 258, 281 | anomaly:alerts, anomaly:key:{key_id} |
| 317, 346, 364, 392, 397 | worker:job:{uuid}... |
| 406, 410 | worker:job:* |
Step 3: Update src/core/cache/redis_cache.rs
Import:
use crate::core::config::REDIS_KEY_PREFIX;
Replace line 10:
// Remove: const KEY_PREFIX: &str = "momentry:cache:";
Update prefixed_key method (line 24):
fn prefixed_key(&self, key: &str) -> String {
format!("{}cache:{}", REDIS_KEY_PREFIX.as_str(), key)
}
Update tests (lines 161-162):
#[test]
fn test_prefixed_key() {
// Note: This test will use the configured prefix
let cache = RedisCache::new().unwrap();
// With default prefix "momentry:"
assert_eq!(cache.prefixed_key("test"), "momentry:cache:test");
assert_eq!(cache.prefixed_key("video:abc"), "momentry:cache:video:abc");
}
Step 4: Update src/main.rs
Change CLI defaults (Lines 691-695):
// Before:
#[arg(long, default_value = "3000")]
port: u16,
// After:
#[arg(long)]
port: Option<u16>,
Update Server match arm (around line 2398):
Commands::Server { host, port } => {
let port = port.unwrap_or_else(|| *crate::core::config::SERVER_PORT);
momentry_core::api::start_server(&host, port).await?;
Ok(())
}
Update Redis key usage (Line 1098):
// Before:
let key = format!("momentry:job:{}:processor:{}", uuid, processor);
// After:
let key = format!(
"{}job:{}:processor:{}",
crate::core::config::REDIS_KEY_PREFIX.as_str(),
uuid,
processor
);
Step 5: Create src/playground.rs
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
// ... same imports as main.rs ...
fn main() -> Result<()> {
// Load development environment first
dotenv::from_filename(".env.development").ok();
tracing_subscriber::fmt::init();
tracing::info!("Starting momentry_playground (development binary)");
tracing::info!("Port: {}", *momentry_core::core::config::SERVER_PORT);
tracing::info!("Redis prefix: {}", *momentry_core::core::config::REDIS_KEY_PREFIX);
let cli = Cli::parse();
// ... rest identical to main.rs ...
}
Step 6: Update Cargo.toml
Add after line 90:
[[bin]]
name = "momentry_playground"
path = "src/playground.rs"
Add dependency (if not present):
dotenv = "0.15"
Step 7: Create .env.development
# Development Environment Configuration
# Used by: momentry_playground binary
# Server Configuration
MOMENTRY_SERVER_PORT=3003
MOMENTRY_REDIS_PREFIX=momentry_dev:
# Worker Configuration (disabled for development)
MOMENTRY_WORKER_ENABLED=false
MOMENTRY_MAX_CONCURRENT=1
MOMENTRY_POLL_INTERVAL=10
# Database (can use separate dev database)
DATABASE_URL=postgres://accusys@localhost:5432/momentry
MONGODB_URL=mongodb://accusys:Test3200Test3200@localhost:27017/admin
# Redis
REDIS_URL=redis://:accusys@localhost:6379
Step 8: Update .env (Production)
Add these lines:
# Production Environment Configuration
# Used by: momentry binary
# Server Configuration
MOMENTRY_SERVER_PORT=3002
MOMENTRY_REDIS_PREFIX=momentry:
# Worker Configuration
MOMENTRY_WORKER_ENABLED=true
MOMENTRY_MAX_CONCURRENT=2
MOMENTRY_POLL_INTERVAL=5
Testing Checklist
1. Build and Run Production Binary
cargo build --release --bin momentry
cargo run --bin momentry -- server
# Expected: Listening on http://127.0.0.1:3002
cargo run --bin momentry -- worker
# Expected: Worker started with momentry: prefix
2. Build and Run Development Binary
cargo build --bin momentry_playground
cargo run --bin momentry_playground -- server
# Expected: Listening on http://127.0.0.1:3003
3. Verify Redis Key Isolation
# Production data
redis-cli KEYS "momentry:*"
# Development data
redis-cli KEYS "momentry_dev:*"
# Should be separate
4. Run Both Simultaneously
# Terminal 1: Production
cargo run --bin momentry -- server
# Terminal 2: Development
cargo run --bin momentry_playground -- server
# Both should run without port conflicts
5. Unit Tests
cargo test --lib
# All tests should pass
Redis Key Structure
Production (momentry:)
momentry:job:{uuid} # Job status
momentry:job:{uuid}:processor:{name} # Processor progress
momentry:progress:{uuid} # Progress pub/sub
momentry:jobs:active # Active job set
momentry:jobs:completed # Completed job set
momentry:jobs:failed # Failed job set
momentry:health:momentry_core # Health status
momentry:cache:{key} # Cache entries
momentry:worker:job:{uuid} # Worker job
momentry:worker:job:{uuid}:processor:{name}
Development (momentry_dev:)
momentry_dev:job:{uuid}
momentry_dev:job:{uuid}:processor:{name}
momentry_dev:progress:{uuid}
momentry_dev:jobs:active
momentry_dev:jobs:completed
momentry_dev:jobs:failed
momentry_dev:health:momentry_core
momentry_dev:cache:{key}
momentry_dev:worker:job:{uuid}
momentry_dev:worker:job:{uuid}:processor:{name}
Potential Issues & Solutions
| Issue | Solution |
|---|---|
dotenv crate not in dependencies |
Add to Cargo.toml |
| Tests use hardcoded prefix | Update tests to use config, or use #[cfg(test)] defaults |
| Worker starts in playground | Check MOMENTRY_WORKER_ENABLED=false in .env.development |
| Port already in use | Graceful error message with suggestion to use --port flag |
| Mixed data in Redis | Ensure prefix is loaded before any Redis operations |
Files Summary
| File | Lines Changed | Purpose |
|---|---|---|
src/core/config.rs |
+15 | Add SERVER_PORT and REDIS_KEY_PREFIX |
src/core/db/redis_client.rs |
~50 | Replace hardcoded prefixes |
src/core/cache/redis_cache.rs |
~10 | Use configurable prefix |
src/main.rs |
~15 | Update CLI defaults, Redis key usage |
src/playground.rs |
NEW (~2800) | Development binary |
Cargo.toml |
+4 | Add binary definition |
.env.development |
NEW (~20) | Development environment |
Total: ~60 lines modified + ~2800 lines new file
Reference Documents
| Document | Purpose |
|---|---|
docs/SERVICES.md |
Port allocations |
docs/MOMENTRY_CORE_REDIS_KEYS.md |
Redis key design |
AGENTS.md |
Code style and conventions |
Version History
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2025-03-25 | OpenCode | Initial implementation plan |