postjevsql.git / tests / latency.rs
1//! The extension's own overhead per call: the mock answers instantly, so
2//! everything measured here is ours (row to JSON, TLS, h2, executor).
3//! Each warm call is in a fresh cache namespace, so it is sent.
4
5use std::time::{Duration, Instant};
6
7use support::{jev_instance, noul};
8use support::mock_jev::{MockJev, Reply};
9
10#[tokio::test(flavor = "multi_thread")]
11async fn overhead_per_call() {
12    let mock = MockJev::start(|_| {
13        Reply::json(200, noul(0.5))
14    })
15    .await;
16    let (_pg, client) = jev_instance(&mock).await;
17    let q = client.prepare("SELECT jev_prob(t, 'q?') FROM tickets t").await.unwrap();
18    let base = client.prepare("SELECT to_json(t)::text FROM tickets t").await.unwrap();
19
20    let time = async |stmt| {
21        let start = Instant::now();
22        client.query_one(stmt, &[]).await.unwrap();
23        start.elapsed()
24    };
25    let cold = time(&q).await;
26    let mut warm: Vec<Duration> = Vec::new();
27    let mut floor: Vec<Duration> = Vec::new();
28    for i in 0..200 {
29        client.batch_execute(&format!("SET jev.cache_namespace = 'warm{i}'")).await.unwrap();
30        warm.push(time(&q).await);
31        floor.push(time(&base).await);
32    }
33    warm.sort();
34    floor.sort();
35    let pct = |v: &[Duration], p: usize| v[v.len() * p / 100];
36    assert_eq!(mock.connections(), 1, "every call reused one connection");
37    assert_eq!(mock.requests().len(), 201);
38    eprintln!(
39        "cold {cold:?} | warm p50 {:?} p99 {:?} | query floor p50 {:?}",
40        pct(&warm, 50),
41        pct(&warm, 99),
42        pct(&floor, 50)
43    );
44}