hyperi_rustlib/governor/mod.rs
1// Project: hyperi-rustlib
2// File: src/governor/mod.rs
3// Purpose: Unified self-regulation pressure governor
4// Language: Rust
5//
6// License: BUSL-1.1
7// Copyright: (c) 2026 HYPERI PTY LIMITED
8
9//! Unified self-regulation governor.
10//!
11//! The pressure seam for the data-plane self-regulation governor. It
12//! combines a set of [`PressureSource`]s into a single normalised
13//! [`level`](UnifiedPressure::level) and a hysteretic
14//! [`should_hold`](UnifiedPressure::should_hold) latch that downstream
15//! stages consult to decide whether to pause inbound work.
16//!
17//! The pieces: [`UnifiedPressure`] (the latch over the sources),
18//! [`InboundGate`] (turns the latch into pause/resume EDGES on the inbound
19//! source -- never the sink), [`ByteBudgetController`] (the AIMD lever sizing
20//! the streaming sub-block budget), [`SelfRegulationConfig`] (the cascade
21//! `self_regulation` section, default-ON), and [`SelfRegulationGovernor`]
22//! (the built bundle the runtime threads into transports + driver).
23//!
24//! Self-regulation is **ON by default** (opt-out `self_regulation.enabled =
25//! false`). See the docs for the full picture: `docs/SELF-REGULATION.md`
26//! (the three brains -- memory is the HARD source of truth, CPU deliberately
27//! dropped), `docs/BACKPRESSURE.md` (gate the source, never the sink), and
28//! `docs/KAFKA-PATH.md` (the three batch sizes + the rho ~ 0.7 loop).
29//!
30//! # Design invariants
31//!
32//! - **HARD signals are never masked.** A HARD source (e.g. the memory
33//! guard) contributes its raw reading to the combined level with no
34//! weight applied. A saturated SOFT signal can never *lower* the level
35//! below what the HARD signal demands, and the absence of a HARD signal
36//! can never be hidden by a busy SOFT one. This is the never-OOM
37//! guarantee: the memory signal always gets through.
38//! - **SOFT signals are weighted.** Each SOFT source's reading is scaled
39//! by its [`weight`](PressureSource::weight) (a sensitivity knob) before
40//! it competes for the level. A low-weight SOFT source at full
41//! saturation cannot force a hold the HARD signal would not.
42//! - **Hysteresis prevents flapping.** The latch arms at `pause_above`
43//! and releases at `resume_below`; between the two it holds its current
44//! state. This stops a reading that oscillates around a single
45//! threshold from rapidly toggling pause/resume.
46//!
47//! The seam is feature-gated (the `governor` feature) and default-ON when
48//! compiled in: the runtime builds the governor and threads it into the
49//! transports + driver unless `self_regulation.enabled = false`. New source
50//! kinds (e.g. a future CPU source) plug in via
51//! [`UnifiedPressure::add_source`] with zero change to the gate API.
52
53mod budget;
54mod config;
55mod gate;
56mod runtime;
57mod source;
58
59pub use budget::{ByteBudgetConfig, ByteBudgetController};
60pub use config::{SelfRegulationConfig, SelfRegulationProfile};
61pub use gate::{Admit, GateActuator, InboundGate, NoopActuator, ObservingActuator};
62pub use runtime::SelfRegulationGovernor;
63pub use source::{
64 Hysteresis, MemoryPressureSource, Pressure, PressureSource, UnifiedPressure,
65 UnifiedPressureSnapshot,
66};