Files
foxhunt/tli/benches/client_performance.rs
jgrusewski 6093eac7bf 🔧 Tonic 0.14 Upgrade: Auto-generated and build system changes
Wave 64-65 cleanup: Proto regeneration and build system updates from Tonic 0.12→0.14 upgrade

Files updated:
- Cargo.lock: Dependency resolution for Tonic 0.14.2
- All build.rs: Updated for tonic-prost-build
- Proto files: Regenerated with tonic-prost 0.14
- Examples/tests: Updated for new gRPC API

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 07:34:26 +02:00

522 lines
16 KiB
Rust

//! Client connection and gRPC performance benchmarks
//!
//! This benchmark suite measures the performance of TLI client operations
//! including connection establishment, request/response cycles, and streaming.
//!
//! ============================================================================
//! TEMPORARILY DISABLED - Missing type definitions
//! ============================================================================
//!
//! This benchmark file references types that don't exist:
//! - `ServiceEndpoints` - not exported from tli crate
//! - `TliClient` - not exported from tli crate
//! - `Order`, `ListOrdersResponse`, `OrderUpdate` - missing proto definitions
//!
//! TODO: Fix by either:
//! 1. Adding missing exports to tli/src/lib.rs
//! 2. Rewriting benchmarks to use available types from tli::prelude
//! 3. Adding missing proto definitions
//!
//! See Wave 36 - Agent 10 for context
//! ============================================================================
#![allow(unused_crate_dependencies)]
// DISABLED: use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
// DISABLED: use std::time::Duration;
// DISABLED: use tli::prelude::*;
// DISABLED: use tli::{ServiceEndpoints, TliClient};
// DISABLED: use tokio::runtime::Runtime;
/*
/// Benchmark client creation and configuration
fn bench_client_creation(c: &mut Criterion) {
let mut group = c.benchmark_group("client_creation");
// Default client creation
group.bench_function("new_default_client", |b| {
b.iter(|| {
let client = TliClient::new();
black_box(client)
})
});
// Custom endpoints client creation
group.bench_function("new_custom_client", |b| {
let endpoints = ServiceEndpoints {
trading_engine: "http://localhost:8080".to_string(),
risk_management: "http://localhost:8081".to_string(),
ml_signals: "http://localhost:8082".to_string(),
market_data: "http://localhost:8083".to_string(),
health_check: "http://localhost:8084".to_string(),
};
b.iter(|| {
let client = TliClient::with_endpoints(black_box(endpoints.clone()));
black_box(client)
})
});
// Service endpoints creation
group.bench_function("service_endpoints_default", |b| {
b.iter(|| {
let endpoints = ServiceEndpoints::default();
black_box(endpoints)
})
});
group.finish();
}
/// Benchmark endpoint parsing and validation
fn bench_endpoint_parsing(c: &mut Criterion) {
let mut group = c.benchmark_group("endpoint_parsing");
let endpoints = vec![
"http://localhost:50052",
"https://remote.example.com:443",
"http://192.168.1.100:8080",
"https://trading-service.internal.company.com:9090",
];
for endpoint in endpoints {
group.bench_with_input(
BenchmarkId::new("endpoint_validation", endpoint),
&endpoint,
|b, &ep| {
b.iter(|| {
// Simulate endpoint validation (similar to what tonic does internally)
let parsed = black_box(ep).parse::<http::Uri>();
black_box(parsed)
})
},
);
}
group.finish();
}
/// Benchmark request/response serialization
fn bench_request_serialization(c: &mut Criterion) {
let mut group = c.benchmark_group("request_serialization");
use tli::proto::trading::*;
// Order submission request
group.bench_function("submit_order_request", |b| {
b.iter(|| {
let request = SubmitOrderRequest {
symbol: black_box("AAPL".to_string()),
side: black_box(OrderSide::Buy as i32),
order_type: black_box(OrderType::Market as i32),
quantity: black_box(100.0),
price: Some(black_box(150.0)),
};
// Simulate serialization
let serialized = serde_json::to_string(&request);
black_box(serialized)
})
});
// Order cancellation request
group.bench_function("cancel_order_request", |b| {
b.iter(|| {
let request = CancelOrderRequest {
order_id: black_box("ORDER_123456".to_string()),
};
let serialized = serde_json::to_string(&request);
black_box(serialized)
})
});
// Configuration request
group.bench_function("get_config_request", |b| {
b.iter(|| {
let request = GetConfigRequest {
key: black_box("max_order_size".to_string()),
};
let serialized = serde_json::to_string(&request);
black_box(serialized)
})
});
// Metrics request
group.bench_function("get_metrics_request", |b| {
b.iter(|| {
let request = GetMetricsRequest {
metric_names: black_box(vec![
"latency_p99".to_string(),
"orders_per_second".to_string(),
"error_rate".to_string(),
]),
};
let serialized = serde_json::to_string(&request);
black_box(serialized)
})
});
group.finish();
}
/// Benchmark response deserialization
fn bench_response_deserialization(c: &mut Criterion) {
let mut group = c.benchmark_group("response_deserialization");
use tli::proto::trading::*;
// Order response
let order_response_json = r#"{
"order_id": "ORDER_123456",
"status": 1,
"message": "Order submitted successfully"
}"#;
group.bench_function("submit_order_response", |b| {
b.iter(|| {
let response: Result<SubmitOrderResponse, _> =
serde_json::from_str(black_box(order_response_json));
black_box(response)
})
});
// System status response
let status_response_json = r#"{
"services": [
{
"name": "trading_engine",
"status": 1,
"message": "Healthy",
"last_check_unix_nanos": 1640995200000000000,
"details": {
"uptime": "99.99%",
"version": "1.0.0"
}
}
]
}"#;
group.bench_function("system_status_response", |b| {
b.iter(|| {
let response: Result<GetSystemStatusResponse, _> =
serde_json::from_str(black_box(status_response_json));
black_box(response)
})
});
// Metrics response with multiple metrics
let metrics_response_json = r#"{
"metrics": [
{
"name": "latency_p99",
"value": 0.025,
"unit": "seconds",
"labels": {"service": "trading"},
"timestamp_unix_nanos": 1640995200000000000
},
{
"name": "orders_per_second",
"value": 150.0,
"unit": "ops/sec",
"labels": {"service": "trading"},
"timestamp_unix_nanos": 1640995200000000000
}
]
}"#;
group.bench_function("metrics_response", |b| {
b.iter(|| {
let response: Result<GetMetricsResponse, _> =
serde_json::from_str(black_box(metrics_response_json));
black_box(response)
})
});
group.finish();
}
/// Benchmark concurrent client operations
fn bench_concurrent_operations(c: &mut Criterion) {
let rt = Runtime::new().unwrap();
let mut group = c.benchmark_group("concurrent_operations");
group.measurement_time(Duration::from_secs(10));
let thread_counts = vec![1, 2, 4, 8, 16];
for thread_count in thread_counts {
group.bench_with_input(
BenchmarkId::new("parallel_client_creation", thread_count),
&thread_count,
|b, &tc| {
b.to_async(&rt).iter(|| async move {
let tasks = (0..tc).map(|i| {
tokio::spawn(async move {
let endpoints = ServiceEndpoints {
trading_engine: format!("http://localhost:{}", 8000 + i),
risk_management: format!("http://localhost:{}", 8100 + i),
ml_signals: format!("http://localhost:{}", 8200 + i),
market_data: format!("http://localhost:{}", 8300 + i),
health_check: format!("http://localhost:{}", 8400 + i),
};
let client = TliClient::with_endpoints(endpoints);
black_box(client)
})
});
futures::future::join_all(tasks).await;
})
},
);
}
group.finish();
}
/// Benchmark error handling performance
fn bench_error_scenarios(c: &mut Criterion) {
let mut group = c.benchmark_group("error_scenarios");
// Connection error simulation
group.bench_function("connection_error", |b| {
b.iter(|| {
let error = TliError::Connection(black_box("Connection refused".to_string()));
let formatted = format!("{}", error);
black_box(formatted)
})
});
// Invalid request error
group.bench_function("invalid_request_error", |b| {
b.iter(|| {
let error = TliError::InvalidRequest(black_box("Invalid order quantity".to_string()));
let formatted = format!("{}", error);
black_box(formatted)
})
});
// Service not connected error
group.bench_function("not_connected_error", |b| {
b.iter(|| {
let error =
TliError::Connection(black_box("Trading service not connected".to_string()));
let formatted = format!("{}", error);
black_box(formatted)
})
});
// Error chain handling
group.bench_function("error_chain", |b| {
b.iter(|| {
let io_error =
std::io::Error::new(std::io::ErrorKind::ConnectionRefused, "Connection refused");
let tli_error: TliError = io_error.into();
let formatted = format!("{}", black_box(tli_error));
black_box(formatted)
})
});
group.finish();
}
/// Benchmark memory usage patterns
fn bench_memory_patterns(c: &mut Criterion) {
let mut group = c.benchmark_group("memory_patterns");
// Client storage patterns
group.bench_function("client_storage", |b| {
b.iter(|| {
let mut clients = Vec::new();
for i in 0..100 {
let endpoints = ServiceEndpoints {
trading_engine: format!("http://host{}:8000", i),
risk_management: format!("http://host{}:8001", i),
ml_signals: format!("http://host{}:8002", i),
market_data: format!("http://host{}:8003", i),
health_check: format!("http://host{}:8004", i),
};
clients.push(TliClient::with_endpoints(endpoints));
}
black_box(clients)
})
});
// Large response handling
group.bench_function("large_response_handling", |b| {
use tli::proto::trading::*;
b.iter(|| {
let mut orders = Vec::new();
for i in 0..1000 {
orders.push(Order {
order_id: format!("ORDER_{:06}", i),
symbol: "AAPL".to_string(),
side: OrderSide::Buy as i32,
order_type: OrderType::Market as i32,
quantity: 100.0,
price: 150.0,
status: OrderStatus::New as i32,
filled_quantity: 0.0,
remaining_quantity: 100.0,
average_price: 0.0,
created_time_unix_nanos: 1640995200000000000,
updated_time_unix_nanos: 1640995200000000000,
});
}
let response = ListOrdersResponse { orders };
black_box(response)
})
});
// Streaming data structures
group.bench_function("streaming_data_structures", |b| {
use tli::proto::trading::*;
b.iter(|| {
let mut updates = Vec::new();
for i in 0..500 {
updates.push(OrderUpdate {
order_id: format!("ORDER_{:06}", i),
symbol: "AAPL".to_string(),
status: if i % 2 == 0 {
OrderStatus::New
} else {
OrderStatus::Filled
} as i32,
filled_quantity: if i % 2 == 0 { 0.0 } else { 100.0 },
timestamp_unix_nanos: 1640995200000000000 + i as i64,
});
}
black_box(updates)
})
});
group.finish();
}
/// Benchmark configuration management
fn bench_config_operations(c: &mut Criterion) {
let mut group = c.benchmark_group("config_operations");
use std::collections::HashMap;
// Configuration parsing
let config_data = vec![
("max_order_size", "10000.0"),
("trading_enabled", "true"),
("risk_limit_usd", "1000000.0"),
("latency_threshold_ms", "25.0"),
("heartbeat_interval_s", "5"),
];
for (key, value) in config_data {
group.bench_with_input(
BenchmarkId::new("config_parsing", key),
&(key, value),
|b, &(k, v)| {
b.iter(|| {
let config = match k {
"trading_enabled" => v.parse::<bool>().map(|b| b.to_string()),
"heartbeat_interval_s" => v.parse::<u64>().map(|n| n.to_string()),
_ => v.parse::<f64>().map(|f| f.to_string()),
};
black_box(config)
})
},
);
}
// Configuration storage
group.bench_function("config_storage", |b| {
b.iter(|| {
let mut config_map = HashMap::new();
for i in 0..100 {
config_map.insert(format!("config_key_{}", i), format!("config_value_{}", i));
}
black_box(config_map)
})
});
group.finish();
}
/// Benchmark health check operations
fn bench_health_check_operations(c: &mut Criterion) {
let mut group = c.benchmark_group("health_check_operations");
use tli::client::ServiceHealth;
// Health status creation
group.bench_function("health_status_creation", |b| {
b.iter(|| {
let status = ServiceHealth {
service: black_box("trading_engine".to_string()),
status: black_box("SERVING".to_string()),
endpoint: black_box("http://localhost:50052".to_string()),
};
black_box(status)
})
});
// Multiple service health aggregation
group.bench_function("health_aggregation", |b| {
b.iter(|| {
let services = vec![
"trading_engine",
"risk_management",
"market_data",
"ml_signals",
"monitoring",
];
let health_statuses: Vec<ServiceHealth> = services
.into_iter()
.enumerate()
.map(|(i, service)| ServiceHealth {
service: service.to_string(),
status: if i % 2 == 0 { "SERVING" } else { "NOT_SERVING" }.to_string(),
endpoint: format!("http://localhost:{}", 50050 + i),
})
.collect();
black_box(health_statuses)
})
});
group.finish();
}
criterion_group!(
benches,
bench_client_creation,
bench_endpoint_parsing,
bench_request_serialization,
bench_response_deserialization,
bench_concurrent_operations,
bench_error_scenarios,
bench_memory_patterns,
bench_config_operations,
bench_health_check_operations
);
criterion_main!(benches);
*/
// Placeholder to keep file valid
fn main() {
println!("Benchmark disabled - see file header for details");
}