Files
the-daily-epub/Cargo.toml
T
thalladaandClaude Fable 5.1 e727d53b85 Cut per-request origin work: batched article loads, no session write per page
The origin was 3–8 ms per page, almost all of it per-statement overhead:
an issue page ran two statements per pick (~55 on a 25-article issue) and
every signed-in page wrote its session row back because `take_flash`
called `Session::remove`, which marks the session modified even when the
key is absent.

- `Db::get_articles` loads an issue's articles and their social rows in
  two statements; both branches of `web::issue::load` use it. The
  single-id and batch queries share one projection via a macro.
- `take_flash` reads before removing, and touches a signed-in session at
  most once a day so the inactivity expiry still slides. Anonymous
  requests never create a session.
- `Server-Timing: app;dur=<ms>` on every response, outermost layer.
- `reject_early_data`: 425 for a non-safe method that arrived as TLS 0-RTT
  data, so nginx `ssl_early_data on` is safe (RFC 8470 §5.2).
- `[profile.release]`: fat LTO, one codegen unit (binary 46 → 29 MB).

Docs: the Cloudflare proxy was retired on 2026-09-05 after measuring
+43 ms per signed-in page from Boston; README reverse-proxy section is
now the direct setup (upstream keepalive, 0-RTT lines) and the CDN
runbook carries a retired-status banner.

Dev seed, app-side: `/` 21 → 5 statements, 3.7 → 1.0 ms; `/feed.xml`
44 → 12, 9.1 → 3.0 ms; session writes per signed-in page 1 → 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Va5eMEmWEnjMXBsBob5FDW
2026-09-05 01:34:39 +00:00

76 lines
2.1 KiB
TOML

[package]
name = "daily-epub"
version = "0.3.0"
edition = "2024"
[dependencies]
ammonia = "4.1.4"
anyhow = "1.0.104"
askama = "0.16.0"
async-trait = "0.1.92"
axum = "0.8.9"
axum-login = { git = "https://github.com/maxcountryman/axum-login.git", rev = "151c72d7a1b4646830f86b4332e6bd6e34d719a7", version = "0.18.0" }
base64 = "0.23.1"
clap = { version = "4.6.6", features = ["derive"] }
dom_smoothie = "0.18.0"
epub-builder = "0.8.3"
figment = { version = "0.10.19", features = ["toml", "env"] }
futures = "0.3.34"
hex = "0.4.3"
hmac = "0.13.0"
image = "0.25.10"
jiff = { version = "0.2.35", features = ["serde"] }
libc = "0.2.189"
password-auth = "1.0.0"
rand = "0.10.2"
reqwest = { version = "0.13.4", default-features = false, features = [
"rustls",
"gzip",
"json",
"charset",
"http2",
"query",
"system-proxy",
] }
resvg = "0.48.1"
rpassword = "7.5.4"
scraper = "0.27.0"
serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.151"
sha2 = "0.11.0"
sqlx = { version = "0.9.0", default-features = false, features = [
"derive",
"json",
"macros",
"migrate",
"runtime-tokio",
"sqlite",
"tls-rustls-ring",
] }
thiserror = "2.0.20"
time = "0.3.55"
tiny-skia = "0.12.0"
tokio = { version = "1.53.1", features = ["full"] }
tokio-util = { version = "0.7.19", features = ["io"] }
toml = "1.1.4"
toml_edit = "0.25"
tower-http = { version = "0.7.0", features = ["trace", "fs", "request-id"] }
tower_governor = { version = "0.8.0", features = ["axum"] }
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
url = { version = "2.5.8", features = ["serde"] }
zip = { version = "6", default-features = false, features = ["deflate"] }
[profile.release]
# Per-request cost in the web server is JSON decode and template render, both
# CPU-bound and spread across crates; whole-program LTO and one codegen unit
# buy a slice of that for a longer release build (tests use the dev profile).
lto = "fat"
codegen-units = 1
[dev-dependencies]
figment = { version = "0.10.19", features = ["test", "toml", "env"] }
roxmltree = "0.21.1"
tempfile = "3.27.0"
tower = { version = "0.5.3", features = ["util"] }