|
9 | 9 | //! plus every HTML page. All static assets (Chart.js + the zoom plugin + |
10 | 10 | //! `chart-init.js` + `style.css` + the two logos) are baked into the |
11 | 11 | //! binary via `include_bytes!` so a deploy is one binary plus a database |
12 | | -//! file. A `tower-http::CompressionLayer` wraps every response — the |
13 | | -//! landing page HTML alone is several hundred KB uncompressed, so this is |
14 | | -//! the single biggest cold-load win. |
| 12 | +//! file. |
| 13 | +//! |
| 14 | +//! The hot website path is a materialized latest-100 read model. DuckDB |
| 15 | +//! remains the source of truth, but default group/chart hydration is served |
| 16 | +//! from precomputed, precompressed in-memory artifacts. See |
| 17 | +//! `benchmarks-website/server/ARCHITECTURE.md` for the higher-level model. |
15 | 18 | //! |
16 | 19 | //! ## Routes |
17 | 20 | //! |
18 | | -//! - `GET /` — landing page, every group rendered as a collapsed |
19 | | -//! `<details>`. The first group's chart payloads are inlined into the |
20 | | -//! HTML; the rest are shells fetched on first toggle. |
21 | | -//! - `GET /chart/{slug}` — single-chart permalink. |
22 | | -//! - `GET /group/{slug}` — every chart in one group on a single page. |
| 21 | +//! - `GET /` — landing page, every group rendered as chart shells plus |
| 22 | +//! versioned shard metadata. Groups hydrate on intent/open. |
| 23 | +//! - `GET /chart/{slug}` — single-chart permalink. Defaults to the |
| 24 | +//! materialized latest-100 window; `?n=all` uses the DB fallback. |
| 25 | +//! - `GET /group/{slug}` — every chart shell in one group on a single page, |
| 26 | +//! opened by default and hydrated through the shard path. |
23 | 27 | //! - `GET /static/...` — the bundled JS / CSS / logos. |
24 | 28 | //! - `GET /api/groups` — flat list of every group with chart-link metadata. |
25 | | -//! - `GET /api/chart/{slug}` — one chart's payload (`commits`, `series`, |
26 | | -//! `unit_kind`, ...). |
27 | | -//! - `GET /api/group/{slug}` — every chart in one group, payload-inlined. |
| 29 | +//! Defaults to a materialized artifact. |
| 30 | +//! - `GET /api/chart/{slug}` — one chart's payload (`history`, `commits`, |
| 31 | +//! `series`, `unit_kind`, ...). Defaults to a materialized latest-100 |
| 32 | +//! artifact; `?n=all` and non-default windows use the DB fallback. |
| 33 | +//! - `GET /api/group/{slug}` — every chart in one group. Defaults to a |
| 34 | +//! materialized latest-100 compatibility artifact. |
| 35 | +//! - `GET /api/artifacts/{generation}/groups/{group_slug}/shards/{index}` — |
| 36 | +//! immutable versioned latest-100 group shard artifact for page hydration. |
28 | 37 | //! - `GET /health` — liveness probe + per-table row counts. |
29 | 38 | //! - `POST /api/ingest` — bearer-gated ingest. See [`ingest`] for the HTTP |
30 | 39 | //! matrix and [`auth`] for the bearer middleware. |
|
33 | 42 | //! |
34 | 43 | //! | Module | Role | |
35 | 44 | //! |---------------|---------------------------------------------------------------------------------------------| |
36 | | -//! | [`app`] | [`app::AppState`] (DB handle + bearer + path) and the Axum router composition. | |
| 45 | +//! | [`app`] | [`app::AppState`] (DB handle + bearer + read store + paths) and the Axum router composition. | |
37 | 46 | //! | [`auth`] | Bearer-token middleware for `/api/ingest`. | |
38 | | -//! | [`db`] | [`db::DbHandle`] task-local connection cloning + the per-fact-table `measurement_id_*` hash functions. | |
| 47 | +//! | [`db`] | [`db::DbHandle`] task-local connection cloning + read backpressure + hash helpers. | |
39 | 48 | //! | [`schema`] | DuckDB DDL ([`schema::SCHEMA_DDL`]) and the wire schema version. | |
40 | 49 | //! | [`records`] | Wire shapes for `POST /api/ingest`. | |
41 | | -//! | [`ingest`] | `POST /api/ingest` handler — envelope validation, transaction, upsert dispatch. | |
| 50 | +//! | [`ingest`] | `POST /api/ingest` handler, cache invalidation, and read-model rebuild scheduling. | |
42 | 51 | //! | [`error`] | [`error::IngestError`] and [`error::ApiError`] with their HTTP-status mapping. | |
43 | 52 | //! | [`slug`] | [`slug::ChartKey`] / [`slug::GroupKey`] enums + base64url round-trip. | |
44 | 53 | //! | [`api`] | Read API. `mod.rs` mounts the handlers; submodules are listed on its module doc. | |
45 | 54 | //! | [`html`] | HTML pages — `mod.rs` mounts the routes; submodules render the body. | |
| 55 | +//! | [`read_model`]| Materialized latest-100 generations and encoded artifact serving. | |
| 56 | +//! | [`query_cache`]| Single-flight cache for non-materialized fallback reads. | |
46 | 57 | //! |
47 | 58 | //! ## Request flow |
48 | 59 | //! |
|
51 | 62 | //! routes skip auth. |
52 | 63 | //! 3. The handler parses body / path / query into typed inputs (e.g. |
53 | 64 | //! [`slug::ChartKey::from_slug`]). |
54 | | -//! 4. The handler hands a closure to [`db::run_blocking`], which clones a |
55 | | -//! task-local DuckDB connection and runs the synchronous call on |
56 | | -//! `tokio::task::spawn_blocking` so the runtime stays free. |
57 | | -//! 5. The closure returns `Result<T, anyhow::Error>`. Errors are mapped |
58 | | -//! into [`error::IngestError`] / [`error::ApiError`] with the right |
59 | | -//! HTTP status. |
60 | | -//! 6. The response is rendered (JSON via [`axum::Json`], HTML via the |
61 | | -//! `maud` router in [`html`]). |
62 | | -//! 7. Every response passes through [`tower_http::compression::CompressionLayer`] |
63 | | -//! on the way out. |
| 65 | +//! 4. For default latest-100 API reads, the handler serves an encoded |
| 66 | +//! [`read_model`] artifact directly from memory. |
| 67 | +//! 5. For ingest, `?n=all`, and non-default windows, the handler hands a |
| 68 | +//! closure to [`db::run_blocking`], which clones a task-local DuckDB |
| 69 | +//! connection and runs synchronous work on `tokio::task::spawn_blocking`. |
| 70 | +//! 6. Fallback chart/group reads go through [`query_cache`] so concurrent |
| 71 | +//! identical misses share one compute. |
| 72 | +//! 7. Errors are mapped into [`error::IngestError`] / [`error::ApiError`] |
| 73 | +//! with the right HTTP status. HTML responses are rendered via `maud`; |
| 74 | +//! hot JSON artifacts are returned as already encoded bytes. |
64 | 75 |
|
65 | 76 | pub mod api; |
66 | 77 | pub mod app; |
|
0 commit comments