use quantum_pulse::{pause, profile, unpause, PausableTimer, ProfileCollector, ProfileOp};
use std::thread;
use std::time::Duration;
#[derive(Debug, ProfileOp)]
enum PaymentOperation {
#[category(name = "Business", description = "Core business logic")]
PaymentProcessing,
OrderValidation,
PaymentFinalization,
#[category(name = "Network", description = "External API calls")]
BankApiCall,
FraudCheckApi,
PaymentGateway,
#[category(name = "Data", description = "Data processing")]
ResponseProcessing,
}
async fn call_bank_api(account: &str) -> Result<String, String> {
println!(" ð Calling bank API for account: {}", account);
thread::sleep(Duration::from_millis(150)); Ok(format!("Bank response for {}", account))
}
async fn call_fraud_detection(amount: f64) -> Result<bool, String> {
println!(" ð Checking fraud score for amount: ${:.2}", amount);
thread::sleep(Duration::from_millis(200)); Ok(amount < 10000.0) }
async fn call_payment_gateway(data: &str) -> Result<String, String> {
println!(" ð Processing payment via gateway: {}", data);
thread::sleep(Duration::from_millis(100)); Ok("Payment successful".to_string())
}
fn validate_payment_request(account: &str, amount: f64) -> Result<(), String> {
println!(" â Validating payment request");
thread::sleep(Duration::from_millis(5)); if account.is_empty() {
return Err("Invalid account".to_string());
}
if amount <= 0.0 {
return Err("Invalid amount".to_string());
}
Ok(())
}
fn prepare_payment_data(account: &str, amount: f64, bank_response: &str) -> String {
println!(" â Preparing payment data");
thread::sleep(Duration::from_millis(10)); format!("Payment: {} -> ${:.2} ({})", account, amount, bank_response)
}
fn finalize_payment(gateway_response: &str) -> String {
println!(" â Finalizing payment");
thread::sleep(Duration::from_millis(8)); format!("Final result: {}", gateway_response)
}
async fn process_payment_with_pause_macros(account: &str, amount: f64) -> Result<String, String> {
println!("\nð§ Method 1: Using pause!()/unpause!() macros");
let result = profile!(PaymentOperation::PaymentProcessing, {
validate_payment_request(account, amount)?;
pause!();
let bank_response = call_bank_api(account).await?;
let fraud_ok = call_fraud_detection(amount).await?;
unpause!();
if !fraud_ok {
return Err("Fraud detected".to_string());
}
let payment_data = prepare_payment_data(account, amount, &bank_response);
pause!();
let gateway_response = call_payment_gateway(&payment_data).await?;
unpause!();
finalize_payment(&gateway_response)
});
Ok(result)
}
async fn process_payment_with_pausable_timer(account: &str, amount: f64) -> Result<String, String> {
println!("\nð§ Method 2: Using PausableTimer");
let mut timer = PausableTimer::new(&PaymentOperation::PaymentProcessing);
validate_payment_request(account, amount)?;
timer.pause();
let bank_response = call_bank_api(account).await?;
let fraud_ok = call_fraud_detection(amount).await?;
timer.resume();
if !fraud_ok {
timer.stop(); return Err("Fraud detected".to_string());
}
let payment_data = prepare_payment_data(account, amount, &bank_response);
timer.pause();
let gateway_response = call_payment_gateway(&payment_data).await?;
timer.resume();
let result = finalize_payment(&gateway_response);
Ok(result)
}
async fn process_payment_with_separate_profiling(
account: &str,
amount: f64,
) -> Result<String, String> {
println!("\nð§ Method 3: Separate profiling (Recommended)");
profile!(PaymentOperation::OrderValidation, {
validate_payment_request(account, amount)?;
});
let bank_response = profile!(PaymentOperation::BankApiCall, {
call_bank_api(account).await?
});
let fraud_ok = profile!(PaymentOperation::FraudCheckApi, {
call_fraud_detection(amount).await?
});
if !fraud_ok {
return Err("Fraud detected".to_string());
}
let payment_data = profile!(PaymentOperation::ResponseProcessing, {
prepare_payment_data(account, amount, &bank_response)
});
let gateway_response = profile!(PaymentOperation::PaymentGateway, {
call_payment_gateway(&payment_data).await?
});
let result = profile!(PaymentOperation::PaymentFinalization, {
finalize_payment(&gateway_response)
});
Ok(result)
}
async fn process_payment_with_nested_profiling(
account: &str,
amount: f64,
) -> Result<String, String> {
println!("\nð§ Method 4: Nested profiling with categorization");
let result = profile!(PaymentOperation::PaymentProcessing, {
profile!(PaymentOperation::OrderValidation, {
validate_payment_request(account, amount)?;
});
let bank_response = profile!(PaymentOperation::BankApiCall, {
call_bank_api(account).await?
});
let fraud_ok = profile!(PaymentOperation::FraudCheckApi, {
call_fraud_detection(amount).await?
});
if !fraud_ok {
return Err("Fraud detected".to_string());
}
let payment_data = profile!(PaymentOperation::ResponseProcessing, {
prepare_payment_data(account, amount, &bank_response)
});
let gateway_response = profile!(PaymentOperation::PaymentGateway, {
call_payment_gateway(&payment_data).await?
});
profile!(PaymentOperation::PaymentFinalization, {
finalize_payment(&gateway_response)
})
});
Ok(result)
}
fn print_profiling_stats(method_name: &str) {
println!("\nð {} Results:", method_name);
let all_stats = ProfileCollector::get_all_stats();
let mut business_stats = Vec::new();
let mut network_stats = Vec::new();
let mut data_stats = Vec::new();
for (name, stats) in all_stats {
if name.starts_with("Business::") {
business_stats.push((name, stats));
} else if name.starts_with("Network::") {
network_stats.push((name, stats));
} else if name.starts_with("Data::") {
data_stats.push((name, stats));
}
}
if !business_stats.is_empty() {
println!(" ðĒ Business Logic (what we care about):");
for (name, stats) in business_stats {
println!(
" - {}: {} calls, avg {}Ξs",
name,
stats.count,
stats.mean().as_micros()
);
}
}
if !data_stats.is_empty() {
println!(" ðū Data Processing:");
for (name, stats) in data_stats {
println!(
" - {}: {} calls, avg {}Ξs",
name,
stats.count,
stats.mean().as_micros()
);
}
}
if !network_stats.is_empty() {
println!(" ð Network Calls (excluded from business metrics):");
for (name, stats) in network_stats {
println!(
" - {}: {} calls, avg {}Ξs",
name,
stats.count,
stats.mean().as_micros()
);
}
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("ð Excluding Network Time from Profiling");
println!("========================================\n");
println!("This example shows different ways to measure only business logic");
println!("performance while excluding network I/O time.\n");
let account = "user123";
let amount = 500.0;
ProfileCollector::clear_all();
let _result1 = process_payment_with_pause_macros(account, amount).await?;
print_profiling_stats("Method 1 (Pause/Unpause Macros)");
ProfileCollector::clear_all();
let _result2 = process_payment_with_pausable_timer(account, amount).await?;
print_profiling_stats("Method 2 (PausableTimer)");
ProfileCollector::clear_all();
let _result3 = process_payment_with_separate_profiling(account, amount).await?;
print_profiling_stats("Method 3 (Separate Profiling)");
ProfileCollector::clear_all();
let _result4 = process_payment_with_nested_profiling(account, amount).await?;
print_profiling_stats("Method 4 (Nested Profiling)");
println!("\nðĄ Recommendations:");
println!(" 1. Use Method 3 (Separate Profiling) for most cases");
println!(" 2. Use Method 1 (pause!/unpause!) for simple exclusions");
println!(" 3. Use Method 2 (PausableTimer) for complex timing control");
println!(" 4. Use Method 4 (Nested) for comprehensive analysis");
println!("\nðŊ Benefits of excluding network time:");
println!(" - Focus on code you can actually optimize");
println!(" - Separate concerns (business logic vs. infrastructure)");
println!(" - More stable performance baselines");
println!(" - Better identification of actual bottlenecks");
Ok(())
}