133 lines
4.8 KiB
Rust
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(())
|
|
} |