36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
import { NodeHttpServer } from "@effect/platform-node"
|
|
import { Effect, Layer } from "effect"
|
|
import { createServer } from "node:http"
|
|
import { Service } from "./httpapi-server"
|
|
|
|
export { Service }
|
|
|
|
export const name = "node-http-server"
|
|
|
|
export type Opts = { port: number; hostname: string }
|
|
|
|
export const layer = (opts: Opts) => {
|
|
const server = createServer()
|
|
const serverRef = { closeStarted: false, forceStop: false }
|
|
const close = server.close.bind(server)
|
|
// Keep shutdown owned by NodeHttpServer, but honor listener.stop(true) by
|
|
// force-closing active HTTP sockets when its finalizer calls server.close().
|
|
server.close = ((callback?: Parameters<typeof server.close>[0]) => {
|
|
serverRef.closeStarted = true
|
|
const result = close(callback)
|
|
if (serverRef.forceStop) server.closeAllConnections()
|
|
return result
|
|
}) as typeof server.close
|
|
return Layer.mergeAll(
|
|
NodeHttpServer.layer(() => server, { port: opts.port, host: opts.hostname, gracefulShutdownTimeout: "1 second" }),
|
|
Layer.succeed(Service)(
|
|
Service.of({
|
|
closeAll: Effect.sync(() => {
|
|
serverRef.forceStop = true
|
|
if (serverRef.closeStarted) server.closeAllConnections()
|
|
}),
|
|
}),
|
|
),
|
|
)
|
|
}
|