summaryrefslogtreecommitdiff
path: root/server/hono_proxy.ts
blob: f729819f44613f7499191459c2d17d06ffece3a4 (plain)
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
68
69
70
71
import {
    BaseRequest,
    Either,
    IEither,
    LogMetricTraceable,
    Metric,
    PenguenoRequest,
    Server,
    Signals,
    TraceUtil,
} from '@emprespresso/pengueno';

import { serve, ServerType } from '@hono/node-server';
import { Hono } from 'hono';

const AppLifetimeMetric = Metric.fromName('HonoAppLifetime').asResult();
const AppRequestMetric = Metric.fromName('HonoAppRequest');

export class HonoProxy {
    private readonly app = LogMetricTraceable.of(new Hono())
        .flatMap(TraceUtil.withTrace(`AppId = ${crypto.randomUUID()}`))
        .flatMap(TraceUtil.withMetricTrace(AppLifetimeMetric));

    constructor(private readonly server: Server) {}

    public async serve(port: number, hostname: string): Promise<IEither<Error, void>> {
        return this.app
            .map((tApp) =>
                Either.fromFailable<Error, ServerType>(() => {
                    const app = tApp.get();
                    app.all('*', async (c) =>
                        tApp
                            .flatMap(TraceUtil.withMetricTrace(AppRequestMetric))
                            .move(<BaseRequest>c.req)
                            .flatMap((tRequest) => PenguenoRequest.from(tRequest))
                            .map((req) => this.server.serve(req))
                            .map(
                                TraceUtil.promiseify((tResponse) => {
                                    tResponse.trace.trace(AppRequestMetric.count.withValue(1.0));
                                    return new Response(tResponse.get().body(), tResponse.get());
                                }),
                            )
                            .get(),
                    );
                    return serve({
                        fetch: (_r) => app.fetch(_r),
                        port,
                        hostname,
                    });
                }),
            )
            .peek(TraceUtil.traceResultingEither())
            .peek((tServe) =>
                tServe
                    .get()
                    .mapRight(() =>
                        tServe.trace.trace(
                            `haii im still listening at http://${hostname}:${port} ~uwu dont think i forgot`,
                        ),
                    ),
            )
            .map((tEitherServer) =>
                tEitherServer
                    .get()
                    .mapRight((server) => tEitherServer.move(server))
                    .flatMapAsync((tServer) => Signals.awaitClose(tServer)),
            )
            .peek(TraceUtil.promiseify(TraceUtil.traceResultingEither(AppLifetimeMetric)))
            .get();
    }
}