This repository has no description
1import { openBash, closeBash } from "./container/index"
2import { createServer } from "./server"
3import { initDb } from "./db"
4import { initMetricsDb } from "./metrics"
5import { shutdown } from "./runner/index"
6import { startDiscordGateway } from "./discord/gateway"
7import { ensureSoulFilePlacement } from "./bootstrap"
8
9const PORT = parseInt(process.env.PORT ?? "3000")
10
11async function main() {
12 console.log("[niri] starting up...")
13
14 await ensureSoulFilePlacement()
15 initDb()
16 initMetricsDb()
17 await openBash()
18
19 let discordGateway: Awaited<ReturnType<typeof startDiscordGateway>> = null
20 try {
21 discordGateway = await startDiscordGateway()
22 } catch (err) {
23 console.warn("[discord gateway] startup failed:", err)
24 }
25
26 const server = createServer()
27
28 await server.listen({ port: PORT, host: "0.0.0.0" })
29 console.log(`[niri] listening on :${PORT}`)
30
31 let shuttingDown = false
32
33 async function gracefulShutdown(sig: string) {
34 if (shuttingDown) return // ignore duplicate signals
35 shuttingDown = true
36 console.log(`\n[niri] ${sig} received, asking niri to journal and rest...`)
37
38 const timeout = new Promise<void>((resolve) =>
39 setTimeout(() => { console.log("[niri] shutdown timed out, forcing exit"); resolve() }, 60_000)
40 )
41
42 await Promise.race([shutdown(), timeout])
43
44 if (discordGateway) await discordGateway.stop()
45 await server.close()
46 closeBash()
47 process.exit(0)
48 }
49
50 // Second SIGINT = user is insisting
51 process.on("SIGINT", async () => {
52 if (shuttingDown) {
53 console.log("\n[niri] force exit")
54 process.exit(1)
55 }
56 await gracefulShutdown("SIGINT")
57 })
58
59 process.on("SIGTERM", () => gracefulShutdown("SIGTERM"))
60}
61
62main().catch((err) => {
63 console.error("[niri] fatal:", err)
64 process.exit(1)
65})