Resolve all BLOCKER/CRITICAL/WARNING findings from the m11p7/p8 review: - tidalctl restore: safe_join path-traversal/Zip-Slip guard + fsync on write - corrupt-WAL checkpoint_seq guard; PITR archive-before-delete - cluster: x-tidal-relayed audit-dedup marker; forward_failures counts 5xx - mTLS/HTTP-TLS handshake hardening; accept-loop EMFILE backoff - per-principal rate-limit + node-token marker-pinning tests - self-heal tier-3 coverage; 5 router-auth tests tidal-stress: measurement-fidelity fixes (schedule-lag p99/max, exact feed-over-SLO verdict, shed annotation) + typed Body, workload.next 184ns->68ns, RoundRobin len==1 short-circuit, HeaderValue cache; new benches/hotpath.rs + lib.rs. perf wave 2: signal_snapshot SmallVec/SignalKey carrier; one-get-per-type ranking pre-pass.
83 lines
3.3 KiB
Rust
83 lines
3.3 KiB
Rust
//! Hot-path micro-benchmarks for the load generator's OWN per-request cost.
|
|
//!
|
|
//! These run with NO server and NO network, so they isolate exactly the work
|
|
//! the generator does per dispatched request — request construction
|
|
//! ([`Workload::next`]) and latency aggregation ([`LatencyHistogram::record`]).
|
|
//! That is the only honest way to answer "is this allocation material?": the
|
|
//! number here is the generator's CPU floor, the thing that must stay far below
|
|
//! the network round-trip it measures, and the before/after the perf sweep is
|
|
//! graded against.
|
|
|
|
use std::hint::black_box;
|
|
use std::time::Duration;
|
|
|
|
use criterion::{Criterion, criterion_group, criterion_main};
|
|
|
|
use tidal_stress::metrics::LatencyHistogram;
|
|
use tidal_stress::workload::{Workload, WritePath, parse_mix};
|
|
|
|
fn make_workload(mix: &str) -> Workload {
|
|
Workload::new(
|
|
// Three read gateways (round-robin), leader-pinned writes => write_bases
|
|
// len == 1, the headline `--leader-url` path (exercises the F4 short-circuit).
|
|
vec![
|
|
"http://10.0.0.1:9500".into(),
|
|
"http://10.0.0.2:9500".into(),
|
|
"http://10.0.0.3:9500".into(),
|
|
],
|
|
vec!["http://10.0.0.1:9500".into()],
|
|
WritePath::Leader,
|
|
parse_mix(mix).expect("mix preset parses"),
|
|
10_000, // corpus
|
|
50_000, // users
|
|
1.3, // hot_skew
|
|
24, // feed_limit
|
|
128, // embedding_dim
|
|
)
|
|
}
|
|
|
|
/// `Workload::next` — the per-dispatched-request construction cost (URL String +
|
|
/// body). `peach` is the headline signal-dominated mix; `writes` forces the body
|
|
/// path on every call; `reads` isolates the URL-only feed/search path.
|
|
fn bench_next(c: &mut Criterion) {
|
|
let wl_peach = make_workload("peach");
|
|
let wl_writes = make_workload("writes");
|
|
let wl_reads = make_workload("reads");
|
|
let mut rng = rand::rng();
|
|
|
|
let mut g = c.benchmark_group("workload_next");
|
|
g.bench_function("peach", |b| b.iter(|| black_box(wl_peach.next(&mut rng))));
|
|
g.bench_function("writes", |b| b.iter(|| black_box(wl_writes.next(&mut rng))));
|
|
g.bench_function("reads", |b| b.iter(|| black_box(wl_reads.next(&mut rng))));
|
|
g.finish();
|
|
}
|
|
|
|
/// `LatencyHistogram::record` — the per-OK-request collector cost (single-writer,
|
|
/// allocation-free), plus the per-stage `percentile` report cost.
|
|
fn bench_histogram(c: &mut Criterion) {
|
|
c.bench_function("histogram_record", |b| {
|
|
let mut h = LatencyHistogram::default();
|
|
// Cheap LCG so successive records land in different buckets rather than
|
|
// hammering one — closer to a real latency distribution.
|
|
let mut state = 0x2545_F491_4F6C_DD1Du64;
|
|
b.iter(|| {
|
|
state = state
|
|
.wrapping_mul(6_364_136_223_846_793_005)
|
|
.wrapping_add(1_442_695_040_888_963_407);
|
|
let ns = (state >> 33) % 200_000_000 + 1; // ~1ns..200ms
|
|
h.record(black_box(Duration::from_nanos(ns)));
|
|
});
|
|
});
|
|
|
|
let mut h = LatencyHistogram::default();
|
|
for i in 1..=100_000u64 {
|
|
h.record(Duration::from_nanos(i * 1_500));
|
|
}
|
|
c.bench_function("histogram_p99", |b| {
|
|
b.iter(|| black_box(h.percentile(black_box(0.99))));
|
|
});
|
|
}
|
|
|
|
criterion_group!(benches, bench_next, bench_histogram);
|
|
criterion_main!(benches);
|