| 1 |
//! Economic Load Balancer |
| 2 |
//! |
| 3 |
//! Load balancing with economic incentives and cost optimization |
| 4 |
|
| 5 |
use serde::{Deserialize, Serialize}; |
| 6 |
use std::collections::HashMap; |
| 7 |
use tokio::time::{Duration, Instant}; |
| 8 |
|
| 9 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 10 |
pub struct EconomicLoadBalancer { |
| 11 |
pub balancer_id: String, |
| 12 |
pub strategy: LoadBalancingStrategy, |
| 13 |
pub cost_optimizer: CostOptimizer, |
| 14 |
pub performance_tracker: PerformanceTracker, |
| 15 |
pub node_pool: NodePool, |
| 16 |
pub routing_policies: Vec<RoutingPolicy>, |
| 17 |
pub economic_metrics: EconomicMetrics, |
| 18 |
} |
| 19 |
|
| 20 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 21 |
pub enum LoadBalancingStrategy { |
| 22 |
CostOptimized, // Minimize total cost |
| 23 |
PerformanceFirst, // Maximize performance regardless of cost |
| 24 |
Balanced, // Balance cost vs performance |
| 25 |
LatencyOptimized, // Minimize response time |
| 26 |
ThroughputMaximized, // Maximize throughput |
| 27 |
EnergyEfficient, // Minimize energy consumption |
| 28 |
RevenueMaximized, // Maximize network revenue |
| 29 |
} |
| 30 |
|
| 31 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 32 |
pub struct CostOptimizer { |
| 33 |
pub optimization_algorithm: OptimizationAlgorithm, |
| 34 |
pub cost_models: HashMap<String, CostModel>, |
| 35 |
pub budget_constraints: BudgetConstraints, |
| 36 |
pub cost_thresholds: CostThresholds, |
| 37 |
} |
| 38 |
|
| 39 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 40 |
pub enum OptimizationAlgorithm { |
| 41 |
GreedyOptimization, |
| 42 |
DynamicProgramming, |
| 43 |
GeneticAlgorithm, |
| 44 |
SimulatedAnnealing, |
| 45 |
LinearProgramming, |
| 46 |
MachineLearning, |
| 47 |
} |
| 48 |
|
| 49 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 50 |
pub struct CostModel { |
| 51 |
pub model_name: String, |
| 52 |
pub cost_components: Vec<CostComponent>, |
| 53 |
pub cost_function: CostFunction, |
| 54 |
pub model_accuracy: f64, |
| 55 |
} |
| 56 |
|
| 57 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 58 |
pub struct CostComponent { |
| 59 |
pub component_name: String, |
| 60 |
pub cost_type: CostType, |
| 61 |
pub unit_cost: f64, |
| 62 |
pub scaling_factor: f64, |
| 63 |
pub minimum_cost: f64, |
| 64 |
pub maximum_cost: Option<f64>, |
| 65 |
} |
| 66 |
|
| 67 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 68 |
pub enum CostType { |
| 69 |
Fixed, // Fixed cost per time period |
| 70 |
Variable, // Variable cost per unit |
| 71 |
Tiered, // Tiered pricing structure |
| 72 |
Peak, // Peak hour pricing |
| 73 |
Spot, // Spot pricing (market-based) |
| 74 |
Reserved, // Reserved capacity pricing |
| 75 |
} |
| 76 |
|
| 77 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 78 |
pub struct CostFunction { |
| 79 |
pub function_type: FunctionType, |
| 80 |
pub parameters: Vec<f64>, |
| 81 |
pub constraints: Vec<Constraint>, |
| 82 |
} |
| 83 |
|
| 84 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 85 |
pub enum FunctionType { |
| 86 |
Linear, |
| 87 |
Quadratic, |
| 88 |
Exponential, |
| 89 |
Logarithmic, |
| 90 |
Piecewise, |
| 91 |
Custom(String), |
| 92 |
} |
| 93 |
|
| 94 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 95 |
pub struct Constraint { |
| 96 |
pub constraint_name: String, |
| 97 |
pub constraint_expression: String, |
| 98 |
pub constraint_type: ConstraintType, |
| 99 |
} |
| 100 |
|
| 101 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 102 |
pub enum ConstraintType { |
| 103 |
Equality, |
| 104 |
LessThan, |
| 105 |
GreaterThan, |
| 106 |
Range, |
| 107 |
} |
| 108 |
|
| 109 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 110 |
pub struct BudgetConstraints { |
| 111 |
pub total_budget: f64, |
| 112 |
pub budget_periods: Vec<BudgetPeriod>, |
| 113 |
pub cost_allocation: HashMap<String, f64>, |
| 114 |
pub overage_policy: OveragePolicy, |
| 115 |
} |
| 116 |
|
| 117 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 118 |
pub struct BudgetPeriod { |
| 119 |
pub period_name: String, |
| 120 |
pub start_time: Instant, |
| 121 |
pub end_time: Instant, |
| 122 |
pub allocated_budget: f64, |
| 123 |
pub spent_budget: f64, |
| 124 |
} |
| 125 |
|
| 126 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 127 |
pub enum OveragePolicy { |
| 128 |
Block, // Block requests when budget exceeded |
| 129 |
Alert, // Alert but continue service |
| 130 |
ScaleDown, // Reduce service capacity |
| 131 |
BorrowFromNext, // Borrow from next period budget |
| 132 |
Emergency, // Use emergency budget |
| 133 |
} |
| 134 |
|
| 135 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 136 |
pub struct CostThresholds { |
| 137 |
pub warning_threshold: f64, // % of budget |
| 138 |
pub critical_threshold: f64, // % of budget |
| 139 |
pub optimization_trigger: f64, // Cost increase % to trigger optimization |
| 140 |
pub emergency_threshold: f64, // Emergency action threshold |
| 141 |
} |
| 142 |
|
| 143 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 144 |
pub struct PerformanceTracker { |
| 145 |
pub metrics: HashMap<String, PerformanceMetric>, |
| 146 |
pub sla_targets: HashMap<String, SLATarget>, |
| 147 |
pub performance_history: Vec<PerformanceSnapshot>, |
| 148 |
} |
| 149 |
|
| 150 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 151 |
pub struct PerformanceMetric { |
| 152 |
pub metric_name: String, |
| 153 |
pub current_value: f64, |
| 154 |
pub target_value: f64, |
| 155 |
pub weight: f64, |
| 156 |
pub trend: Trend, |
| 157 |
} |
| 158 |
|
| 159 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 160 |
pub enum Trend { |
| 161 |
Improving, |
| 162 |
Stable, |
| 163 |
Degrading, |
| 164 |
} |
| 165 |
|
| 166 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 167 |
pub struct SLATarget { |
| 168 |
pub target_name: String, |
| 169 |
pub target_value: f64, |
| 170 |
pub measurement_window: Duration, |
| 171 |
pub penalty_per_violation: f64, |
| 172 |
pub current_compliance: f64, |
| 173 |
} |
| 174 |
|
| 175 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 176 |
pub struct PerformanceSnapshot { |
| 177 |
pub timestamp: Instant, |
| 178 |
pub response_time: Duration, |
| 179 |
pub throughput: f64, |
| 180 |
pub error_rate: f64, |
| 181 |
pub cost_per_request: f64, |
| 182 |
pub node_utilization: HashMap<String, f64>, |
| 183 |
} |
| 184 |
|
| 185 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 186 |
pub struct NodePool { |
| 187 |
pub nodes: HashMap<String, LoadBalancerNode>, |
| 188 |
pub node_tiers: HashMap<String, NodeTier>, |
| 189 |
pub capacity_management: CapacityManagement, |
| 190 |
} |
| 191 |
|
| 192 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 193 |
pub struct LoadBalancerNode { |
| 194 |
pub node_id: String, |
| 195 |
pub node_tier: String, |
| 196 |
pub capacity: NodeCapacity, |
| 197 |
pub pricing: NodePricing, |
| 198 |
pub performance_profile: PerformanceProfile, |
| 199 |
pub availability: NodeAvailability, |
| 200 |
pub health_status: HealthStatus, |
| 201 |
pub economic_score: f64, |
| 202 |
} |
| 203 |
|
| 204 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 205 |
pub struct NodeCapacity { |
| 206 |
pub max_requests_per_second: f64, |
| 207 |
pub max_concurrent_connections: u32, |
| 208 |
pub storage_capacity_gb: u64, |
| 209 |
pub bandwidth_mbps: f64, |
| 210 |
pub cpu_cores: u32, |
| 211 |
pub memory_gb: u32, |
| 212 |
} |
| 213 |
|
| 214 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 215 |
pub struct NodePricing { |
| 216 |
pub pricing_model: PricingModel, |
| 217 |
pub cost_per_request: f64, |
| 218 |
pub cost_per_gb_storage: f64, |
| 219 |
pub cost_per_gb_bandwidth: f64, |
| 220 |
pub cost_per_hour: f64, |
| 221 |
pub bulk_discounts: Vec<BulkDiscount>, |
| 222 |
} |
| 223 |
|
| 224 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 225 |
pub enum PricingModel { |
| 226 |
PayPerUse, |
| 227 |
Subscription, |
| 228 |
Reserved, |
| 229 |
Spot, |
| 230 |
Hybrid, |
| 231 |
} |
| 232 |
|
| 233 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 234 |
pub struct BulkDiscount { |
| 235 |
pub threshold: f64, |
| 236 |
pub discount_percentage: f64, |
| 237 |
pub applies_to: Vec<String>, |
| 238 |
} |
| 239 |
|
| 240 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 241 |
pub struct PerformanceProfile { |
| 242 |
pub average_response_time: Duration, |
| 243 |
pub throughput_capacity: f64, |
| 244 |
pub reliability_score: f64, |
| 245 |
pub latency_percentiles: LatencyPercentiles, |
| 246 |
pub resource_efficiency: ResourceEfficiency, |
| 247 |
} |
| 248 |
|
| 249 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 250 |
pub struct LatencyPercentiles { |
| 251 |
pub p50: Duration, |
| 252 |
pub p90: Duration, |
| 253 |
pub p95: Duration, |
| 254 |
pub p99: Duration, |
| 255 |
} |
| 256 |
|
| 257 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 258 |
pub struct ResourceEfficiency { |
| 259 |
pub cpu_efficiency: f64, |
| 260 |
pub memory_efficiency: f64, |
| 261 |
pub storage_efficiency: f64, |
| 262 |
pub network_efficiency: f64, |
| 263 |
} |
| 264 |
|
| 265 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 266 |
pub struct NodeAvailability { |
| 267 |
pub current_availability: f64, |
| 268 |
pub scheduled_maintenance: Vec<MaintenanceWindow>, |
| 269 |
pub availability_history: Vec<AvailabilityRecord>, |
| 270 |
pub uptime_sla: f64, |
| 271 |
} |
| 272 |
|
| 273 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 274 |
pub struct MaintenanceWindow { |
| 275 |
pub start_time: Instant, |
| 276 |
pub end_time: Instant, |
| 277 |
pub maintenance_type: MaintenanceType, |
| 278 |
pub impact_level: ImpactLevel, |
| 279 |
} |
| 280 |
|
| 281 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 282 |
pub enum MaintenanceType { |
| 283 |
Routine, |
| 284 |
Security, |
| 285 |
Hardware, |
| 286 |
Software, |
| 287 |
Emergency, |
| 288 |
} |
| 289 |
|
| 290 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 291 |
pub enum ImpactLevel { |
| 292 |
None, |
| 293 |
Low, |
| 294 |
Medium, |
| 295 |
High, |
| 296 |
Complete, |
| 297 |
} |
| 298 |
|
| 299 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 300 |
pub struct AvailabilityRecord { |
| 301 |
pub timestamp: Instant, |
| 302 |
pub availability_percentage: f64, |
| 303 |
pub downtime_duration: Duration, |
| 304 |
pub downtime_reason: String, |
| 305 |
} |
| 306 |
|
| 307 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 308 |
pub enum HealthStatus { |
| 309 |
Healthy, |
| 310 |
Warning, |
| 311 |
Critical, |
| 312 |
Maintenance, |
| 313 |
Offline, |
| 314 |
} |
| 315 |
|
| 316 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 317 |
pub struct NodeTier { |
| 318 |
pub tier_name: String, |
| 319 |
pub tier_level: u8, |
| 320 |
pub performance_guarantees: Vec<PerformanceGuarantee>, |
| 321 |
pub cost_characteristics: CostCharacteristics, |
| 322 |
pub resource_limits: ResourceLimits, |
| 323 |
} |
| 324 |
|
| 325 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 326 |
pub struct PerformanceGuarantee { |
| 327 |
pub metric_name: String, |
| 328 |
pub guaranteed_value: f64, |
| 329 |
pub measurement_period: Duration, |
| 330 |
pub penalty_if_violated: f64, |
| 331 |
} |
| 332 |
|
| 333 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 334 |
pub struct CostCharacteristics { |
| 335 |
pub cost_predictability: f64, // 0.0 = unpredictable, 1.0 = very predictable |
| 336 |
pub cost_stability: f64, // Price volatility measure |
| 337 |
pub bulk_pricing_available: bool, |
| 338 |
pub commitment_discounts: Vec<CommitmentDiscount>, |
| 339 |
} |
| 340 |
|
| 341 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 342 |
pub struct CommitmentDiscount { |
| 343 |
pub commitment_duration: Duration, |
| 344 |
pub discount_percentage: f64, |
| 345 |
pub minimum_usage: f64, |
| 346 |
} |
| 347 |
|
| 348 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 349 |
pub struct ResourceLimits { |
| 350 |
pub max_cpu_utilization: f64, |
| 351 |
pub max_memory_utilization: f64, |
| 352 |
pub max_storage_utilization: f64, |
| 353 |
pub max_network_utilization: f64, |
| 354 |
pub burst_limits: BurstLimits, |
| 355 |
} |
| 356 |
|
| 357 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 358 |
pub struct BurstLimits { |
| 359 |
pub cpu_burst_multiplier: f64, |
| 360 |
pub memory_burst_multiplier: f64, |
| 361 |
pub network_burst_multiplier: f64, |
| 362 |
pub burst_duration: Duration, |
| 363 |
} |
| 364 |
|
| 365 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 366 |
pub struct CapacityManagement { |
| 367 |
pub auto_scaling: AutoScalingConfig, |
| 368 |
pub capacity_planning: CapacityPlanning, |
| 369 |
pub resource_allocation: ResourceAllocation, |
| 370 |
} |
| 371 |
|
| 372 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 373 |
pub struct AutoScalingConfig { |
| 374 |
pub enabled: bool, |
| 375 |
pub scaling_policies: Vec<ScalingPolicy>, |
| 376 |
pub cooldown_periods: CooldownPeriods, |
| 377 |
pub scaling_limits: ScalingLimits, |
| 378 |
} |
| 379 |
|
| 380 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 381 |
pub struct ScalingPolicy { |
| 382 |
pub policy_name: String, |
| 383 |
pub trigger_metric: String, |
| 384 |
pub scale_up_threshold: f64, |
| 385 |
pub scale_down_threshold: f64, |
| 386 |
pub scaling_action: ScalingAction, |
| 387 |
pub economic_constraints: EconomicConstraints, |
| 388 |
} |
| 389 |
|
| 390 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 391 |
pub enum ScalingAction { |
| 392 |
AddNodes { count: u32 }, |
| 393 |
RemoveNodes { count: u32 }, |
| 394 |
ChangeNodeTier { target_tier: String }, |
| 395 |
AdjustCapacity { percentage: f64 }, |
| 396 |
} |
| 397 |
|
| 398 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 399 |
pub struct EconomicConstraints { |
| 400 |
pub max_cost_increase: f64, |
| 401 |
pub roi_threshold: f64, |
| 402 |
pub payback_period: Duration, |
| 403 |
pub budget_limit: f64, |
| 404 |
} |
| 405 |
|
| 406 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 407 |
pub struct CooldownPeriods { |
| 408 |
pub scale_up_cooldown: Duration, |
| 409 |
pub scale_down_cooldown: Duration, |
| 410 |
pub policy_change_cooldown: Duration, |
| 411 |
} |
| 412 |
|
| 413 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 414 |
pub struct ScalingLimits { |
| 415 |
pub min_nodes: u32, |
| 416 |
pub max_nodes: u32, |
| 417 |
pub max_scaling_rate: f64, // nodes per minute |
| 418 |
pub max_cost_per_hour: f64, |
| 419 |
} |
| 420 |
|
| 421 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 422 |
pub struct CapacityPlanning { |
| 423 |
pub planning_horizon: Duration, |
| 424 |
pub demand_forecasts: Vec<DemandForecast>, |
| 425 |
pub capacity_recommendations: Vec<CapacityRecommendation>, |
| 426 |
pub cost_projections: Vec<CostProjection>, |
| 427 |
} |
| 428 |
|
| 429 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 430 |
pub struct DemandForecast { |
| 431 |
pub forecast_period: Duration, |
| 432 |
pub predicted_demand: f64, |
| 433 |
pub confidence_interval: (f64, f64), |
| 434 |
pub seasonal_factors: Vec<SeasonalFactor>, |
| 435 |
} |
| 436 |
|
| 437 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 438 |
pub struct SeasonalFactor { |
| 439 |
pub factor_name: String, |
| 440 |
pub multiplier: f64, |
| 441 |
pub time_period: Duration, |
| 442 |
pub recurrence_pattern: String, |
| 443 |
} |
| 444 |
|
| 445 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 446 |
pub struct CapacityRecommendation { |
| 447 |
pub recommendation_id: String, |
| 448 |
pub recommended_action: RecommendedAction, |
| 449 |
pub justification: String, |
| 450 |
pub expected_benefit: f64, |
| 451 |
pub implementation_cost: f64, |
| 452 |
pub risk_assessment: RiskAssessment, |
| 453 |
} |
| 454 |
|
| 455 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 456 |
pub enum RecommendedAction { |
| 457 |
IncreaseCapacity { amount: f64 }, |
| 458 |
DecreaseCapacity { amount: f64 }, |
| 459 |
ChangeConfiguration { new_config: String }, |
| 460 |
MigrateWorkloads { target_nodes: Vec<String> }, |
| 461 |
OptimizePlacement, |
| 462 |
} |
| 463 |
|
| 464 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 465 |
pub struct RiskAssessment { |
| 466 |
pub risk_level: RiskLevel, |
| 467 |
pub risk_factors: Vec<RiskFactor>, |
| 468 |
pub mitigation_strategies: Vec<String>, |
| 469 |
pub contingency_plans: Vec<String>, |
| 470 |
} |
| 471 |
|
| 472 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 473 |
pub enum RiskLevel { |
| 474 |
Low, |
| 475 |
Medium, |
| 476 |
High, |
| 477 |
Critical, |
| 478 |
} |
| 479 |
|
| 480 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 481 |
pub struct RiskFactor { |
| 482 |
pub factor_name: String, |
| 483 |
pub probability: f64, |
| 484 |
pub impact: f64, |
| 485 |
pub description: String, |
| 486 |
} |
| 487 |
|
| 488 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 489 |
pub struct CostProjection { |
| 490 |
pub projection_period: Duration, |
| 491 |
pub projected_cost: f64, |
| 492 |
pub cost_breakdown: HashMap<String, f64>, |
| 493 |
pub cost_drivers: Vec<String>, |
| 494 |
pub optimization_opportunities: Vec<String>, |
| 495 |
} |
| 496 |
|
| 497 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 498 |
pub struct ResourceAllocation { |
| 499 |
pub allocation_strategy: AllocationStrategy, |
| 500 |
pub resource_reservations: Vec<ResourceReservation>, |
| 501 |
pub allocation_efficiency: f64, |
| 502 |
pub utilization_targets: HashMap<String, f64>, |
| 503 |
} |
| 504 |
|
| 505 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 506 |
pub enum AllocationStrategy { |
| 507 |
FirstFit, |
| 508 |
BestFit, |
| 509 |
WorstFit, |
| 510 |
CostOptimized, |
| 511 |
PerformanceOptimized, |
| 512 |
Balanced, |
| 513 |
} |
| 514 |
|
| 515 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 516 |
pub struct ResourceReservation { |
| 517 |
pub reservation_id: String, |
| 518 |
pub reserved_resources: HashMap<String, f64>, |
| 519 |
pub reservation_duration: Duration, |
| 520 |
pub cost_per_hour: f64, |
| 521 |
pub utilization_commitment: f64, |
| 522 |
} |
| 523 |
|
| 524 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 525 |
pub struct RoutingPolicy { |
| 526 |
pub policy_name: String, |
| 527 |
pub routing_rules: Vec<RoutingRule>, |
| 528 |
pub traffic_shaping: TrafficShaping, |
| 529 |
pub cost_controls: CostControls, |
| 530 |
} |
| 531 |
|
| 532 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 533 |
pub struct RoutingRule { |
| 534 |
pub rule_priority: u8, |
| 535 |
pub conditions: Vec<RoutingCondition>, |
| 536 |
pub actions: Vec<RoutingAction>, |
| 537 |
pub cost_impact: f64, |
| 538 |
} |
| 539 |
|
| 540 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 541 |
pub struct RoutingCondition { |
| 542 |
pub condition_type: ConditionType, |
| 543 |
pub condition_value: String, |
| 544 |
pub operator: ComparisonOperator, |
| 545 |
} |
| 546 |
|
| 547 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 548 |
pub enum ConditionType { |
| 549 |
RequestSize, |
| 550 |
ClientLocation, |
| 551 |
TimeOfDay, |
| 552 |
LoadLevel, |
| 553 |
CostBudget, |
| 554 |
NodeTier, |
| 555 |
ServiceType, |
| 556 |
} |
| 557 |
|
| 558 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 559 |
pub enum ComparisonOperator { |
| 560 |
Equals, |
| 561 |
NotEquals, |
| 562 |
GreaterThan, |
| 563 |
LessThan, |
| 564 |
Contains, |
| 565 |
InRange, |
| 566 |
} |
| 567 |
|
| 568 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 569 |
pub struct RoutingAction { |
| 570 |
pub action_type: ActionType, |
| 571 |
pub target_nodes: Vec<String>, |
| 572 |
pub weight_distribution: HashMap<String, f64>, |
| 573 |
pub failover_targets: Vec<String>, |
| 574 |
} |
| 575 |
|
| 576 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 577 |
pub enum ActionType { |
| 578 |
RouteToTier, |
| 579 |
RouteToSpecificNode, |
| 580 |
RouteByPerformance, |
| 581 |
RouteByCost, |
| 582 |
LoadBalance, |
| 583 |
Reject, |
| 584 |
} |
| 585 |
|
| 586 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 587 |
pub struct TrafficShaping { |
| 588 |
pub rate_limiting: RateLimiting, |
| 589 |
pub priority_queues: Vec<PriorityQueue>, |
| 590 |
pub bandwidth_allocation: BandwidthAllocation, |
| 591 |
} |
| 592 |
|
| 593 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 594 |
pub struct RateLimiting { |
| 595 |
pub requests_per_second: f64, |
| 596 |
pub burst_size: u32, |
| 597 |
pub cost_per_excess_request: f64, |
| 598 |
pub throttling_strategy: ThrottlingStrategy, |
| 599 |
} |
| 600 |
|
| 601 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 602 |
pub enum ThrottlingStrategy { |
| 603 |
DropExcess, |
| 604 |
QueueWithDelay, |
| 605 |
RedirectToLowerTier, |
| 606 |
DynamicPricing, |
| 607 |
} |
| 608 |
|
| 609 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 610 |
pub struct PriorityQueue { |
| 611 |
pub queue_name: String, |
| 612 |
pub priority_level: u8, |
| 613 |
pub bandwidth_share: f64, |
| 614 |
pub cost_multiplier: f64, |
| 615 |
} |
| 616 |
|
| 617 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 618 |
pub struct BandwidthAllocation { |
| 619 |
pub total_bandwidth: f64, |
| 620 |
pub guaranteed_bandwidth: HashMap<String, f64>, |
| 621 |
pub burstable_bandwidth: HashMap<String, f64>, |
| 622 |
pub cost_per_mbps: f64, |
| 623 |
} |
| 624 |
|
| 625 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 626 |
pub struct CostControls { |
| 627 |
pub cost_limits: CostLimits, |
| 628 |
pub cost_monitoring: CostMonitoring, |
| 629 |
pub cost_optimization: CostOptimizationSettings, |
| 630 |
} |
| 631 |
|
| 632 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 633 |
pub struct CostLimits { |
| 634 |
pub daily_limit: f64, |
| 635 |
pub monthly_limit: f64, |
| 636 |
pub per_request_limit: f64, |
| 637 |
pub overage_handling: OverageHandling, |
| 638 |
} |
| 639 |
|
| 640 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 641 |
pub enum OverageHandling { |
| 642 |
Block, |
| 643 |
Alert, |
| 644 |
Throttle, |
| 645 |
UpgradeTier, |
| 646 |
} |
| 647 |
|
| 648 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 649 |
pub struct CostMonitoring { |
| 650 |
pub monitoring_frequency: Duration, |
| 651 |
pub cost_alerts: Vec<CostAlert>, |
| 652 |
pub cost_reporting: CostReporting, |
| 653 |
} |
| 654 |
|
| 655 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 656 |
pub struct CostAlert { |
| 657 |
pub alert_name: String, |
| 658 |
pub threshold_percentage: f64, |
| 659 |
pub notification_channels: Vec<String>, |
| 660 |
pub escalation_policy: String, |
| 661 |
} |
| 662 |
|
| 663 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 664 |
pub struct CostReporting { |
| 665 |
pub report_frequency: Duration, |
| 666 |
pub report_recipients: Vec<String>, |
| 667 |
pub cost_breakdown_detail: DetailLevel, |
| 668 |
} |
| 669 |
|
| 670 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 671 |
pub enum DetailLevel { |
| 672 |
Summary, |
| 673 |
Detailed, |
| 674 |
Granular, |
| 675 |
} |
| 676 |
|
| 677 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 678 |
pub struct CostOptimizationSettings { |
| 679 |
pub auto_optimization: bool, |
| 680 |
pub optimization_frequency: Duration, |
| 681 |
pub optimization_targets: Vec<OptimizationTarget>, |
| 682 |
pub optimization_constraints: Vec<OptimizationConstraint>, |
| 683 |
} |
| 684 |
|
| 685 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 686 |
pub struct OptimizationTarget { |
| 687 |
pub target_name: String, |
| 688 |
pub target_metric: String, |
| 689 |
pub target_value: f64, |
| 690 |
pub weight: f64, |
| 691 |
} |
| 692 |
|
| 693 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 694 |
pub struct OptimizationConstraint { |
| 695 |
pub constraint_name: String, |
| 696 |
pub constraint_expression: String, |
| 697 |
pub constraint_type: ConstraintType, |
| 698 |
} |
| 699 |
|
| 700 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 701 |
pub struct EconomicMetrics { |
| 702 |
pub cost_efficiency: f64, |
| 703 |
pub revenue_per_request: f64, |
| 704 |
pub profit_margin: f64, |
| 705 |
pub cost_per_performance_unit: f64, |
| 706 |
pub return_on_investment: f64, |
| 707 |
pub economic_value_added: f64, |
| 708 |
} |
| 709 |
|
| 710 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 711 |
pub struct ResourceWeight { |
| 712 |
pub node_id: String, |
| 713 |
pub performance_weight: f64, |
| 714 |
pub cost_weight: f64, |
| 715 |
pub reliability_weight: f64, |
| 716 |
pub composite_score: f64, |
| 717 |
} |
| 718 |
|
| 719 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 720 |
pub struct CostOptimizedRouting { |
| 721 |
pub routing_algorithm: RoutingAlgorithm, |
| 722 |
pub cost_matrix: HashMap<String, HashMap<String, f64>>, |
| 723 |
pub performance_requirements: PerformanceRequirements, |
| 724 |
pub optimization_results: OptimizationResults, |
| 725 |
} |
| 726 |
|
| 727 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 728 |
pub enum RoutingAlgorithm { |
| 729 |
Dijkstra, |
| 730 |
AStar, |
| 731 |
FloydWarshall, |
| 732 |
BellmanFord, |
| 733 |
Custom(String), |
| 734 |
} |
| 735 |
|
| 736 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 737 |
pub struct PerformanceRequirements { |
| 738 |
pub max_latency: Duration, |
| 739 |
pub min_throughput: f64, |
| 740 |
pub max_error_rate: f64, |
| 741 |
pub availability_requirement: f64, |
| 742 |
} |
| 743 |
|
| 744 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 745 |
pub struct OptimizationResults { |
| 746 |
pub optimal_routes: Vec<OptimalRoute>, |
| 747 |
pub total_cost: f64, |
| 748 |
pub cost_savings: f64, |
| 749 |
pub performance_impact: f64, |
| 750 |
} |
| 751 |
|
| 752 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 753 |
pub struct OptimalRoute { |
| 754 |
pub source: String, |
| 755 |
pub destination: String, |
| 756 |
pub path: Vec<String>, |
| 757 |
pub total_cost: f64, |
| 758 |
pub expected_performance: PerformanceMetrics, |
| 759 |
} |
| 760 |
|
| 761 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 762 |
pub struct PerformanceMetrics { |
| 763 |
pub latency: Duration, |
| 764 |
pub throughput: f64, |
| 765 |
pub reliability: f64, |
| 766 |
pub cost_efficiency: f64, |
| 767 |
} |
| 768 |
|
| 769 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 770 |
pub struct PerformancePricing { |
| 771 |
pub pricing_tiers: Vec<PerformanceTier>, |
| 772 |
pub dynamic_pricing: DynamicPricing, |
| 773 |
pub performance_guarantees: Vec<PerformanceGuarantee>, |
| 774 |
pub penalty_structure: PenaltyStructure, |
| 775 |
} |
| 776 |
|
| 777 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 778 |
pub struct PerformanceTier { |
| 779 |
pub tier_name: String, |
| 780 |
pub performance_level: f64, |
| 781 |
pub base_price: f64, |
| 782 |
pub performance_multiplier: f64, |
| 783 |
pub included_features: Vec<String>, |
| 784 |
} |
| 785 |
|
| 786 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 787 |
pub struct DynamicPricing { |
| 788 |
pub enabled: bool, |
| 789 |
pub pricing_factors: Vec<PricingFactor>, |
| 790 |
pub adjustment_frequency: Duration, |
| 791 |
pub price_bounds: PriceBounds, |
| 792 |
} |
| 793 |
|
| 794 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 795 |
pub struct PricingFactor { |
| 796 |
pub factor_name: String, |
| 797 |
pub current_value: f64, |
| 798 |
pub weight: f64, |
| 799 |
pub impact_on_price: f64, |
| 800 |
} |
| 801 |
|
| 802 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 803 |
pub struct PriceBounds { |
| 804 |
pub minimum_price: f64, |
| 805 |
pub maximum_price: f64, |
| 806 |
pub maximum_change_per_period: f64, |
| 807 |
} |
| 808 |
|
| 809 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 810 |
pub struct PenaltyStructure { |
| 811 |
pub sla_violations: Vec<SLAViolationPenalty>, |
| 812 |
pub performance_penalties: Vec<PerformancePenalty>, |
| 813 |
pub availability_penalties: Vec<AvailabilityPenalty>, |
| 814 |
} |
| 815 |
|
| 816 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 817 |
pub struct SLAViolationPenalty { |
| 818 |
pub violation_type: String, |
| 819 |
pub penalty_amount: f64, |
| 820 |
pub penalty_calculation: PenaltyCalculation, |
| 821 |
} |
| 822 |
|
| 823 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 824 |
pub struct PerformancePenalty { |
| 825 |
pub metric_name: String, |
| 826 |
pub threshold: f64, |
| 827 |
pub penalty_per_unit: f64, |
| 828 |
pub maximum_penalty: f64, |
| 829 |
} |
| 830 |
|
| 831 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 832 |
pub struct AvailabilityPenalty { |
| 833 |
pub availability_threshold: f64, |
| 834 |
pub penalty_percentage: f64, |
| 835 |
pub grace_period: Duration, |
| 836 |
} |
| 837 |
|
| 838 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 839 |
pub struct PenaltyCalculation { |
| 840 |
pub calculation_method: CalculationMethod, |
| 841 |
pub base_amount: f64, |
| 842 |
pub escalation_factor: f64, |
| 843 |
} |
| 844 |
|
| 845 |
#[derive(Debug, Clone, Serialize, Deserialize)] |
| 846 |
pub enum CalculationMethod { |
| 847 |
Fixed, |
| 848 |
Proportional, |
| 849 |
Progressive, |
| 850 |
Exponential, |
| 851 |
} |
| 852 |
|
| 853 |
impl EconomicLoadBalancer { |
| 854 |
pub fn new(balancer_id: String, strategy: LoadBalancingStrategy) -> Self { |
| 855 |
Self { |
| 856 |
balancer_id, |
| 857 |
strategy, |
| 858 |
cost_optimizer: CostOptimizer::new(), |
| 859 |
performance_tracker: PerformanceTracker::new(), |
| 860 |
node_pool: NodePool::new(), |
| 861 |
routing_policies: Vec::new(), |
| 862 |
economic_metrics: EconomicMetrics::default(), |
| 863 |
} |
| 864 |
} |
| 865 |
|
| 866 |
pub async fn route_request(&self, request: &Request) -> Result<String, Box<dyn std::error::Error>> { |
| 867 |
let candidate_nodes = self.get_candidate_nodes(request).await?; |
| 868 |
let optimal_node = self.select_optimal_node(&candidate_nodes, request).await?; |
| 869 |
|
| 870 |
Ok(optimal_node) |
| 871 |
} |
| 872 |
|
| 873 |
pub async fn optimize_routing(&mut self) -> Result<(), Box<dyn std::error::Error>> { |
| 874 |
let optimization_result = self.cost_optimizer.optimize_placement(&self.node_pool).await?; |
| 875 |
self.apply_optimization_results(optimization_result).await?; |
| 876 |
|
| 877 |
Ok(()) |
| 878 |
} |
| 879 |
|
| 880 |
async fn get_candidate_nodes(&self, request: &Request) -> Result<Vec<String>, Box<dyn std::error::Error>> { |
| 881 |
let mut candidates = Vec::new(); |
| 882 |
|
| 883 |
for (node_id, node) in &self.node_pool.nodes { |
| 884 |
if self.meets_requirements(node, request) { |
| 885 |
candidates.push(node_id.clone()); |
| 886 |
} |
| 887 |
} |
| 888 |
|
| 889 |
Ok(candidates) |
| 890 |
} |
| 891 |
|
| 892 |
async fn select_optimal_node(&self, candidates: &[String], request: &Request) -> Result<String, Box<dyn std::error::Error>> { |
| 893 |
let mut best_node = None; |
| 894 |
let mut best_score = f64::NEG_INFINITY; |
| 895 |
|
| 896 |
for node_id in candidates { |
| 897 |
if let Some(node) = self.node_pool.nodes.get(node_id) { |
| 898 |
let score = self.calculate_node_score(node, request).await?; |
| 899 |
if score > best_score { |
| 900 |
best_score = score; |
| 901 |
best_node = Some(node_id.clone()); |
| 902 |
} |
| 903 |
} |
| 904 |
} |
| 905 |
|
| 906 |
best_node.ok_or_else(|| "No suitable node found".into()) |
| 907 |
} |
| 908 |
|
| 909 |
async fn calculate_node_score(&self, node: &LoadBalancerNode, request: &Request) -> Result<f64, Box<dyn std::error::Error>> { |
| 910 |
let cost_score = self.calculate_cost_score(node, request); |
| 911 |
let performance_score = self.calculate_performance_score(node, request); |
| 912 |
let availability_score = node.availability.current_availability; |
| 913 |
|
| 914 |
let composite_score = match self.strategy { |
| 915 |
LoadBalancingStrategy::CostOptimized => cost_score * 0.7 + performance_score * 0.2 + availability_score * 0.1, |
| 916 |
LoadBalancingStrategy::PerformanceFirst => performance_score * 0.7 + availability_score * 0.2 + cost_score * 0.1, |
| 917 |
LoadBalancingStrategy::Balanced => cost_score * 0.4 + performance_score * 0.4 + availability_score * 0.2, |
| 918 |
LoadBalancingStrategy::LatencyOptimized => { |
| 919 |
let latency_score = 1.0 / (node.performance_profile.average_response_time.as_millis() as f64 + 1.0); |
| 920 |
latency_score * 0.6 + performance_score * 0.3 + cost_score * 0.1 |
| 921 |
}, |
| 922 |
_ => cost_score * 0.33 + performance_score * 0.33 + availability_score * 0.33, |
| 923 |
}; |
| 924 |
|
| 925 |
Ok(composite_score) |
| 926 |
} |
| 927 |
|
| 928 |
fn calculate_cost_score(&self, node: &LoadBalancerNode, _request: &Request) -> f64 { |
| 929 |
// Higher cost = lower score |
| 930 |
let max_cost = 1.0; // Normalize to maximum expected cost |
| 931 |
let normalized_cost = node.pricing.cost_per_request / max_cost; |
| 932 |
1.0 - normalized_cost.min(1.0) |
| 933 |
} |
| 934 |
|
| 935 |
fn calculate_performance_score(&self, node: &LoadBalancerNode, _request: &Request) -> f64 { |
| 936 |
node.performance_profile.reliability_score |
| 937 |
} |
| 938 |
|
| 939 |
fn meets_requirements(&self, node: &LoadBalancerNode, request: &Request) -> bool { |
| 940 |
matches!(node.health_status, HealthStatus::Healthy) && |
| 941 |
node.capacity.max_requests_per_second >= request.expected_load |
| 942 |
} |
| 943 |
|
| 944 |
async fn apply_optimization_results(&mut self, _results: OptimizationResults) -> Result<(), Box<dyn std::error::Error>> { |
| 945 |
// Apply the optimization results to routing policies |
| 946 |
Ok(()) |
| 947 |
} |
| 948 |
} |
| 949 |
|
| 950 |
// Helper structures |
| 951 |
#[derive(Debug, Clone)] |
| 952 |
pub struct Request { |
| 953 |
pub request_id: String, |
| 954 |
pub expected_load: f64, |
| 955 |
pub latency_requirement: Duration, |
| 956 |
pub cost_sensitivity: f64, |
| 957 |
} |
| 958 |
|
| 959 |
impl CostOptimizer { |
| 960 |
fn new() -> Self { |
| 961 |
Self { |
| 962 |
optimization_algorithm: OptimizationAlgorithm::GreedyOptimization, |
| 963 |
cost_models: HashMap::new(), |
| 964 |
budget_constraints: BudgetConstraints::default(), |
| 965 |
cost_thresholds: CostThresholds::default(), |
| 966 |
} |
| 967 |
} |
| 968 |
|
| 969 |
async fn optimize_placement(&self, _node_pool: &NodePool) -> Result<OptimizationResults, Box<dyn std::error::Error>> { |
| 970 |
// Placeholder implementation |
| 971 |
Ok(OptimizationResults { |
| 972 |
optimal_routes: Vec::new(), |
| 973 |
total_cost: 0.0, |
| 974 |
cost_savings: 0.0, |
| 975 |
performance_impact: 0.0, |
| 976 |
}) |
| 977 |
} |
| 978 |
} |
| 979 |
|
| 980 |
impl PerformanceTracker { |
| 981 |
fn new() -> Self { |
| 982 |
Self { |
| 983 |
metrics: HashMap::new(), |
| 984 |
sla_targets: HashMap::new(), |
| 985 |
performance_history: Vec::new(), |
| 986 |
} |
| 987 |
} |
| 988 |
} |
| 989 |
|
| 990 |
impl NodePool { |
| 991 |
fn new() -> Self { |
| 992 |
Self { |
| 993 |
nodes: HashMap::new(), |
| 994 |
node_tiers: HashMap::new(), |
| 995 |
capacity_management: CapacityManagement::default(), |
| 996 |
} |
| 997 |
} |
| 998 |
} |
| 999 |
|
| 1000 |
// Default implementations |
| 1001 |
impl Default for BudgetConstraints { |
| 1002 |
fn default() -> Self { |
| 1003 |
Self { |
| 1004 |
total_budget: 10000.0, |
| 1005 |
budget_periods: Vec::new(), |
| 1006 |
cost_allocation: HashMap::new(), |
| 1007 |
overage_policy: OveragePolicy::Alert, |
| 1008 |
} |
| 1009 |
} |
| 1010 |
} |
| 1011 |
|
| 1012 |
impl Default for CostThresholds { |
| 1013 |
fn default() -> Self { |
| 1014 |
Self { |
| 1015 |
warning_threshold: 0.8, |
| 1016 |
critical_threshold: 0.95, |
| 1017 |
optimization_trigger: 0.2, |
| 1018 |
emergency_threshold: 1.1, |
| 1019 |
} |
| 1020 |
} |
| 1021 |
} |
| 1022 |
|
| 1023 |
impl Default for CapacityManagement { |
| 1024 |
fn default() -> Self { |
| 1025 |
Self { |
| 1026 |
auto_scaling: AutoScalingConfig { |
| 1027 |
enabled: true, |
| 1028 |
scaling_policies: Vec::new(), |
| 1029 |
cooldown_periods: CooldownPeriods { |
| 1030 |
scale_up_cooldown: Duration::from_secs(300), |
| 1031 |
scale_down_cooldown: Duration::from_secs(600), |
| 1032 |
policy_change_cooldown: Duration::from_secs(900), |
| 1033 |
}, |
| 1034 |
scaling_limits: ScalingLimits { |
| 1035 |
min_nodes: 1, |
| 1036 |
max_nodes: 100, |
| 1037 |
max_scaling_rate: 5.0, |
| 1038 |
max_cost_per_hour: 1000.0, |
| 1039 |
}, |
| 1040 |
}, |
| 1041 |
capacity_planning: CapacityPlanning { |
| 1042 |
planning_horizon: Duration::from_secs(30 * 24 * 3600), // 30 days |
| 1043 |
demand_forecasts: Vec::new(), |
| 1044 |
capacity_recommendations: Vec::new(), |
| 1045 |
cost_projections: Vec::new(), |
| 1046 |
}, |
| 1047 |
resource_allocation: ResourceAllocation { |
| 1048 |
allocation_strategy: AllocationStrategy::Balanced, |
| 1049 |
resource_reservations: Vec::new(), |
| 1050 |
allocation_efficiency: 0.85, |
| 1051 |
utilization_targets: HashMap::new(), |
| 1052 |
}, |
| 1053 |
} |
| 1054 |
} |
| 1055 |
} |
| 1056 |
|
| 1057 |
impl Default for EconomicMetrics { |
| 1058 |
fn default() -> Self { |
| 1059 |
Self { |
| 1060 |
cost_efficiency: 0.0, |
| 1061 |
revenue_per_request: 0.0, |
| 1062 |
profit_margin: 0.0, |
| 1063 |
cost_per_performance_unit: 0.0, |
| 1064 |
return_on_investment: 0.0, |
| 1065 |
economic_value_added: 0.0, |
| 1066 |
} |
| 1067 |
} |
| 1068 |
} |