Repository navigation
v3.1.7
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 forreadContentDsl(...)before returning. The DSL load runs onDispatchers.IO, so the Ktor engine starts serving immediately and/pingis 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 inIntercepts.ktreturns503 Service UnavailablewithRetry-After: 5and a cachedContentLoadingPagefor 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 Nsuntil the load finishes — useful for spotting deploys where the DSL evaluation has stalled or failed. Replaces the old one-shotSTARTUP_DELAY_SECSwarning. - Encapsulated readiness flag.
ReadingBatServer.contentReadCountis now private; the interceptor usesisContentReady: Booleanand the admin diagnostics page usescontentLoadCount: Int.Property.STARTUP_DELAY_SECSand itsapplication-test.conf/application-travis.confentries are removed. - Revert of the 3.1.6 health-route split.
/pingis folded back intoadminRoutes; the new readiness gate makes the earlyhealthRoutesregistration unnecessary. - Test coverage. New
ContentLoadingPageTestpins down the rendered HTML and the lazy-cache invariant, andContentReadinessInterceptorTestdrives the gate end-to-end through KtortestApplication(blocked path → 503 + loading page; allowlisted paths → 200; post-markContentLoaded()→ handler reached). - Makefile. New
clean-alltarget runsclean+clean-docsand wipes the per-project.gradlecaches.
Full Changelog: 3.1.6...3.1.7