///|
/// Startup and shutdown hooks (← FastAPI's `on_event`). A server drives them over the ASGI
/// lifespan protocol; here a test client does, in-process: startup in registration order, the
/// requests in between, shutdown in reverse, so a resource is released before whatever it was
/// opened from. What a startup hook stores in the lifespan state is in every request's
/// `ctx.state()`.
///
/// moon run src/examples/23-lifespan --target native
#coverage.skip
async fn main {
let log : Array[String] = []
let app = @moonapi.App::new()
app.on_startup(state => {
state["db"] = "pool-1"
log.push("connect db")
})
app.on_startup(_ => log.push("warm cache"))
app.on_shutdown(_ => log.push("close db"))
app.on_shutdown(_ => log.push("drop cache"))
app.get("/db", ctx => {
@moonapi.json(200, ctx.state().get("db").unwrap_or(Json::null()))
})
let client = @testing.Client::new(app.to_asgi())
client.lifespan(() => log.push("request saw \{client.get("/db").text()}"))
println(log.join(" -> "))
}