Skip to content

v3.1.7

Choose a tag to compare

@pambrose pambrose released this 04 May 18:44
· 61 commits to master since this release
1d12846

Background DSL content loading and a readiness gate so platform health checks pass during cold starts.

Highlights

  • Non-blocking startup. Application.module() no longer waits for readContentDsl(...) before returning. The DSL load runs on Dispatchers.IO, so the Ktor engine starts serving immediately and /ping is reachable from the first second of the deploy. This fixes DigitalOcean (and similar platforms) timing out the deployment health check while GitHub-backed content is still being fetched and evaluated.
  • Loading page. A new Plugins-phase interceptor in Intercepts.kt returns 503 Service Unavailable with Retry-After: 5 and a cached ContentLoadingPage for any user-facing path until the first DSL load completes. The page meta-refreshes every 5 seconds, so browsers automatically pick up the site once content is ready. A small allowlist (/ping, /static/*, favicon, robots, ktor shutdown) stays available throughout startup.
  • Heartbeat warnings. A 10-second polling loop logs Content not loaded after Ns until the load finishes — useful for spotting deploys where the DSL evaluation has stalled or failed. Replaces the old one-shot STARTUP_DELAY_SECS warning.
  • Encapsulated readiness flag. ReadingBatServer.contentReadCount is now private; the interceptor uses isContentReady: Boolean and the admin diagnostics page uses contentLoadCount: Int. Property.STARTUP_DELAY_SECS and its application-test.conf / application-travis.conf entries are removed.
  • Revert of the 3.1.6 health-route split. /ping is folded back into adminRoutes; the new readiness gate makes the early healthRoutes registration unnecessary.
  • Test coverage. New ContentLoadingPageTest pins down the rendered HTML and the lazy-cache invariant, and ContentReadinessInterceptorTest drives the gate end-to-end through Ktor testApplication (blocked path → 503 + loading page; allowlisted paths → 200; post-markContentLoaded() → handler reached).
  • Makefile. New clean-all target runs clean + clean-docs and wipes the per-project .gradle caches.

Full Changelog: 3.1.6...3.1.7