Skip to main content

hyperi_rustlib/scaling/
mod.rs

1// Project:   hyperi-rustlib
2// File:      src/scaling/mod.rs
3// Purpose:   Scaling pressure calculation for KEDA autoscaling
4// Language:  Rust
5//
6// License:   BUSL-1.1
7// Copyright: (c) 2026 HYPERI PTY LIMITED
8
9//! Scaling pressure calculation for autoscaler integration.
10//!
11//! Produces a 0.0-100.0 composite metric based on weighted application
12//! signals with two hard gates (circuit breaker, memory pressure).
13//! Designed for KEDA but works with any autoscaler that reads Prometheus
14//! gauges.
15//!
16//! ## Architecture
17//!
18//! ```text
19//! App signals ──→ ScalingPressure ──→ {prefix}_scaling_pressure gauge
20//!                  ├─ Gate: circuit breaker open → 0.0
21//!                  ├─ Gate: memory ≥ threshold → 100.0
22//!                  └─ Weighted composite → 0.0-100.0
23//! ```
24//!
25//! ## Usage
26//!
27//! 1. Define components with weights and saturation points
28//! 2. Create `ScalingPressure` with base config + components
29//! 3. Update component values from your pipeline (lock-free)
30//! 4. Call `calculate()` when rendering Prometheus metrics
31//!
32//! ```rust
33//! use hyperi_rustlib::scaling::{ScalingPressure, ScalingPressureConfig, ScalingComponent};
34//!
35//! let pressure = ScalingPressure::new(
36//!     ScalingPressureConfig::default(),
37//!     vec![
38//!         ScalingComponent::new("kafka_lag", 0.35, 100_000.0),
39//!         ScalingComponent::new("buffer_depth", 0.25, 10_000.0),
40//!         ScalingComponent::new("memory", 0.40, 1.0),
41//!     ],
42//! );
43//!
44//! // Update from pipeline (lock-free, call from any thread)
45//! pressure.set_component("kafka_lag", 50_000.0);
46//! pressure.set_memory(400_000_000, 1_000_000_000);
47//!
48//! // Render in Prometheus endpoint
49//! let value = pressure.calculate();
50//! assert!(value >= 0.0 && value <= 100.0);
51//! ```
52//!
53//! ## CPU Scaling
54//!
55//! CPU is intentionally **not** included in the composite. KEDA's native
56//! CPU trigger reads from the Kubernetes metrics-server (container-level
57//! CPU utilisation). Configure both triggers independently in your
58//! KEDA `ScaledObject`:
59//!
60//! - `scaling_pressure` gauge → Prometheus scaler (app-level signals)
61//! - CPU utilisation → CPU scaler (container-level, via metrics-server)
62//!
63//! KEDA scales to the MAX of all triggers.
64
65mod config;
66mod pressure;
67mod rate_window;
68
69pub use config::{ScalingComponent, ScalingPressureConfig};
70pub use pressure::{ComponentSnapshot, GateType, PressureSnapshot, ScalingPressure};
71pub use rate_window::RateWindow;