-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathprogram.ts
More file actions
67 lines (59 loc) · 2.5 KB
/
program.ts
File metadata and controls
67 lines (59 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { HttpMiddleware, HttpServer, HttpServerRequest } from "@effect/platform"
import { NodeHttpServer } from "@effect/platform-node"
import { Console, Effect, Layer, Option } from "effect"
import { createServer } from "node:http"
import { makeRouter } from "./http.js"
import { initializeAccountPool } from "./services/account-pool.js"
import { initializeAgentState } from "./services/agents.js"
import { startOutboxPolling } from "./services/federation.js"
const resolvePort = (env: Record<string, string | undefined>): number => {
const raw = env["DOCKER_GIT_API_PORT"] ?? env["PORT"]
const parsed = raw === undefined ? Number.NaN : Number(raw)
return Number.isFinite(parsed) && parsed > 0 ? parsed : 3334
}
const requestLogger = HttpMiddleware.make((httpApp) =>
Effect.gen(function*(_) {
const request = yield* _(HttpServerRequest.HttpServerRequest)
const startedAt = Date.now()
const id = `${startedAt}-${Math.floor(Math.random() * 1e6)}`
const remote = Option.getOrElse(request.remoteAddress, () => "unknown")
yield* _(Console.log(`[api req ${id}] ${request.method} ${request.url} remote=${remote}`))
return yield* _(
httpApp.pipe(
Effect.tap((response) =>
Console.log(
`[api res ${id}] ${request.method} ${request.url} status=${response.status} ms=${Date.now() - startedAt}`
)
),
Effect.tapError((error) =>
Console.error(`[api err ${id}] ${request.method} ${request.url} ${String(error)}`)
)
)
)
})
)
export const program = (() => {
const port = resolvePort(process.env)
const router = makeRouter()
const app = router.pipe(HttpServer.serve(requestLogger), HttpServer.withLogAddress)
const server = createServer()
const serverLayer = NodeHttpServer.layer(() => server, { port })
const pollingInterval = parseInt(process.env["DOCKER_GIT_OUTBOX_POLLING_INTERVAL_MS"] ?? "5000", 10)
return Effect.scoped(
Console.log(`docker-git api boot port=${port}`).pipe(
Effect.zipRight(initializeAgentState()),
Effect.zipRight(
Effect.tryPromise({ try: () => initializeAccountPool(), catch: () => new Error("account pool init failed") }).pipe(
Effect.catchAll(() => Effect.void)
)
),
Effect.zipRight(
Console.log(`docker-git outbox polling interval=${pollingInterval}ms`)
),
Effect.zipRight(
Effect.fork(startOutboxPolling(pollingInterval))
),
Effect.zipRight(Layer.launch(Layer.provide(app, serverLayer)))
)
)
})()