From 0fda26f1d54dc74689080dc20a73198e4ca23dfa Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 1 Jul 2026 19:32:36 +0000 Subject: [PATCH] otel: real auto-refresh dashboard + HTTP self-warm (kills cold p99) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dashboard: drop the non-functional data-on-load SSE attr; add so it genuinely live-updates (the host serves single-body responses, no server-push SSE). /otel/stream stays a snapshot for pollers. serve.sh: replace the ineffective boot-time make-app warmup (wrong JIT context) with a backgrounded self-warmer that GETs the hot pages over real HTTP (bash /dev/tcp โ€” no curl in the image) once /health is up, so the first real visitor after a restart gets ~78ms instead of the one-time ~2.5s serving-JIT compile. --- lib/host/otel.sx | 8 +++++++- lib/host/serve.sh | 30 ++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/host/otel.sx b/lib/host/otel.sx index b42f6426..f8db6aca 100644 --- a/lib/host/otel.sx +++ b/lib/host/otel.sx @@ -376,8 +376,14 @@ (lt (otel/latest-trace)) (traces (otel/recent-traces))) (quasiquote - (div :id "otel-dashboard" :data-on-load "@get('/otel/stream')" + (div :id "otel-dashboard" + ;; The host serves single-body responses (no server-push SSE), so the + ;; dashboard stays live by reloading itself โ€” every 3s it re-renders the + ;; latest metrics + trace. /otel/stream remains a snapshot of the newest + ;; span for any client that wants to poll it. + (meta :http-equiv "refresh" :content "3") (h1 "OpenTelemetry") + (p :style "font-size:0.8em;opacity:0.7" "live ยท auto-refreshes every 3s") (h2 "metrics") (unquote (otel/-metrics-strip m)) (h2 "latest trace") diff --git a/lib/host/serve.sh b/lib/host/serve.sh index 6afde9d5..300d5503 100755 --- a/lib/host/serve.sh +++ b/lib/host/serve.sh @@ -28,6 +28,28 @@ fi PORT="${HOST_PORT:-8910}" +# Self-warm the SERVING JIT. The FIRST HTTP request after a restart pays a one-time +# ~2.5s cost: the shared request path (session middleware + router + instrumented +# handlers + blog render) JIT-compiles under the http-listen resolver, a context a +# boot-time render can't reach. So once the server is answering, we GET the hot +# pages ONCE over real HTTP to absorb that compile before a visitor does (~2.5s -> +# ~78ms warm). The container image has no curl/wget, so we speak HTTP over bash's +# /dev/tcp. Runs detached (survives the exec below); exits after warming. +_warm_serving_jit() { + local path + # wait until /health answers 200 (the port opens only after all modules load) + for _ in $(seq 1 180); do + case "$( { exec 3<>/dev/tcp/127.0.0.1/"$PORT" && printf 'GET /health HTTP/1.0\r\nHost: x\r\n\r\n' >&3 && head -1 <&3; exec 3>&- 3<&-; } 2>/dev/null )" in + *200*) break ;; + esac + sleep 0.5 + done + for path in / /welcome /nt-live-encore /otel; do + { exec 3<>/dev/tcp/127.0.0.1/"$PORT" && printf 'GET %s HTTP/1.0\r\nHost: x\r\n\r\n' "$path" >&3 && cat <&3 >/dev/null; exec 3>&- 3<&-; } 2>/dev/null + done +} +_warm_serving_jit & + # Modules: every load line from conformance.sh's MODULES list, minus the ledger # (not needed to serve). server.sx supplies host/serve. MODULES=( @@ -195,14 +217,6 @@ EPOCH=1 echo "(epoch $EPOCH)" echo "(eval \"(define host/-serve-groups (list host/static-routes otel/routes host/feed-routes host/relations-routes (host/blog-write-routes (fn (tok) nil)) host/blog-routes))\")" EPOCH=$((EPOCH+1)) - # JIT warmup: render the hot pages once through a throwaway app so the FIRST real - # visitor after a restart doesn't eat the cold-compile cost. The blog render path - # (comp-fold + relations + typed-block) JIT-compiles on first call โ€” that was the - # ~2.5s p99 on /:slug, vs ~78ms warm. Reset the otel ring after so warmup spans - # don't skew the live metrics. - echo "(epoch $EPOCH)" - echo "(eval \"(let ((warm (host/make-app host/-serve-groups))) (begin (warm (dream-request \\\"GET\\\" \\\"/\\\" {} \\\"\\\")) (warm (dream-request \\\"GET\\\" \\\"/welcome\\\" {} \\\"\\\")) (warm (dream-request \\\"GET\\\" \\\"/nt-live-encore\\\" {} \\\"\\\")) (warm (dream-request \\\"GET\\\" \\\"/otel\\\" {} \\\"\\\")) (otel/reset!) nil))\")" - EPOCH=$((EPOCH+1)) echo "(epoch $EPOCH)" echo "(eval \"(host/serve $PORT host/-serve-groups)\")" } | exec "$SX_SERVER"