host: durable lazy sessions — logins survive a restart

Sessions were in-memory, so a restart logged everyone out (same class as the
relation wipe). Move them to the durable store, but LAZILY so anonymous/crawler
traffic doesn't spam it: session/create mints a sid with no row; the row appears
on the first session/set (a login). A per-boot epoch (one durable write at
startup, host/session-init!) keeps sids unique across restarts without a write
per request.

- lib/host/session.sx: lazy backend (create = no row, set = create row,
  exists = row written) + epoch/in-memory-counter sid generation.
- serve.sh: point the session store at the durable backend + host/session-init!.
- blog.sx: host/current-principal is now a durable read, so host/auth-footer
  (home + post footers) had to move OUT of the quasiquote into let bindings —
  a perform during page-tree build raises VmSuspended (the whole site 500'd for
  a beat). Principal computed once per page.
- 2 session tests: create writes no row, set creates the row.

249/249. Verified live: site renders (anon + authed), login + footer survive a
container force-recreate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-28 16:37:26 +00:00
parent 71dd040d80
commit b0b0a0592b
4 changed files with 73 additions and 38 deletions

View File

@@ -126,6 +126,18 @@
(dream-status (host-se-secure host-se-live-cookie)))
401)
;; ── lazy persistence: only a written (logged-in) session leaves a durable row ──
(host-se-test "session/create writes no row (anonymous leaves no durable trace)"
(host/session-backend {:op "session/exists" :sid (host/session-backend {:op "session/create"})})
false)
(host-se-test "session/set creates the row (a login persists)"
(let ((sid (host/session-backend {:op "session/create"})))
(begin
(host/session-backend {:op "session/set" :sid sid :key :principal :val "bob"})
(list (host/session-backend {:op "session/exists" :sid sid})
(host/session-backend {:op "session/get" :sid sid :key :principal}))))
(list true "bob"))
(define host-se-tests-run!
(fn ()
{:total (+ host-se-pass host-se-fail)