9.0 KiB
9.0 KiB
Playground Binary Implementation Plan
| Item | Content |
|---|---|
| Author | Warren |
| Created | 2026-03-23 |
| Document Version | V1.0 |
Version History
| Version | Date | Purpose | Operator | Tool/Model |
|---|---|---|---|---|
| V1.0 | 2026-03-23 | Create implementation plan | Warren | OpenCode |
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 |