rhailib/examples/run_benchmark_demo.rs
2025-06-12 05:21:52 +03:00

133 lines
4.8 KiB
Rust

//! 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<dyn std::error::Error>> {
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(())
}