//! Demo script showing how to run the hybrid performance benchmark //! //! This example demonstrates: //! 1. Starting workers programmatically //! 2. Running the Lua batch script //! 3. Collecting and displaying statistics use rhailib::{RedisStatsCollector, WorkerManager, clear_redis_test_data, check_redis_connection}; use redis::{Client, Commands}; use std::fs; use std::time::Duration; const REDIS_URL: &str = "redis://localhost:6379"; const CIRCLE_NAME: &str = "demo_circle"; fn main() -> Result<(), Box> { env_logger::init(); println!("๐Ÿš€ Rhailib Hybrid Performance Benchmark Demo"); println!("============================================"); // Check Redis connection println!("๐Ÿ“ก Checking Redis connection..."); check_redis_connection(REDIS_URL)?; println!("โœ… Redis connection successful"); // Clear any existing test data println!("๐Ÿงน Clearing existing test data..."); clear_redis_test_data(REDIS_URL)?; println!("โœ… Test data cleared"); // Load Lua script println!("๐Ÿ“œ Loading Lua batch script..."); let lua_script = fs::read_to_string("scripts/run_rhai_batch.lua")?; println!("โœ… Lua script loaded ({} bytes)", lua_script.len()); // Start workers println!("๐Ÿ‘ท Starting 2 worker processes..."); let mut worker_manager = WorkerManager::new(); worker_manager.start_workers(2, CIRCLE_NAME, REDIS_URL)?; worker_manager.wait_for_workers_ready(Duration::from_secs(3))?; println!("โœ… Workers started and ready"); // Connect to Redis let redis_client = Client::open(REDIS_URL)?; let mut conn = redis_client.get_connection()?; // Execute batch workload println!("๐ŸŽฏ Submitting batch of 100 tasks..."); let batch_id = format!("demo_batch_{}", chrono::Utc::now().timestamp_millis()); let simple_script = "let x = 42; x * 2"; let start_time = std::time::Instant::now(); let result: redis::Value = redis::cmd("EVAL") .arg(&lua_script) .arg(0) // No keys .arg(CIRCLE_NAME) .arg(100) // task count .arg(simple_script) .arg(&batch_id) .query(&mut conn)?; let submission_time = start_time.elapsed(); println!("โœ… Batch submitted in {:?}", submission_time); // Parse result if let redis::Value::Data(data) = result { let response: serde_json::Value = serde_json::from_slice(&data)?; println!("๐Ÿ“Š Batch info: {}", serde_json::to_string_pretty(&response)?); } // Wait for completion and collect statistics println!("โณ Waiting for batch completion..."); let stats_collector = RedisStatsCollector::new(REDIS_URL)?; let completed = stats_collector.wait_for_batch_completion( &batch_id, 100, Duration::from_secs(30), )?; if !completed { println!("โš ๏ธ Batch did not complete within timeout"); return Ok(()); } println!("โœ… Batch completed!"); // Collect and display statistics println!("๐Ÿ“ˆ Collecting performance statistics..."); let timings = stats_collector.collect_batch_timings(&batch_id)?; let stats = stats_collector.calculate_stats(&timings); println!("\n๐Ÿ“Š PERFORMANCE RESULTS"); println!("======================"); println!("Total tasks: {}", stats.total_tasks); println!("Completed tasks: {}", stats.completed_tasks); println!("Failed tasks: {}", stats.failed_tasks); println!("Error rate: {:.2}%", stats.error_rate); println!("Throughput: {:.2} tasks/second", stats.throughput_tps); println!("Batch duration: {:.2} ms", stats.batch_duration_ms); println!("\nLatency Statistics:"); println!(" Min: {:.2} ms", stats.latency_stats.min_ms); println!(" Max: {:.2} ms", stats.latency_stats.max_ms); println!(" Mean: {:.2} ms", stats.latency_stats.mean_ms); println!(" Median: {:.2} ms", stats.latency_stats.median_ms); println!(" P95: {:.2} ms", stats.latency_stats.p95_ms); println!(" P99: {:.2} ms", stats.latency_stats.p99_ms); println!(" Std Dev: {:.2} ms", stats.latency_stats.std_dev_ms); // Show some individual task timings println!("\n๐Ÿ” Sample Task Timings (first 10):"); for (i, timing) in timings.iter().take(10).enumerate() { println!(" Task {}: {} -> {} ({:.2}ms, status: {})", i + 1, timing.task_id, timing.status, timing.latency_ms, timing.status ); } // Cleanup println!("\n๐Ÿงน Cleaning up..."); stats_collector.cleanup_batch_data(&batch_id)?; worker_manager.shutdown()?; println!("โœ… Cleanup complete"); println!("\n๐ŸŽ‰ Demo completed successfully!"); Ok(()) }