From 5454eea191cb04ead82acd63fd3bc0245fac3791 Mon Sep 17 00:00:00 2001 From: Guide Fari Date: Sat, 11 Jul 2026 01:01:13 +0200 Subject: [PATCH] feat(vps): swap entry point to Effect toWebHandler (Step 2b) Step 2b of the Hono -> Effect HttpApi migration (docs/migration-effect-http-api.md). Serving topology change, zero route behavior change -- still 100% Hono fallback. - apps/vps/src/index.ts: Bun.serve's fetch now points at effectWebHandler.handler instead of app.fetch directly. Every request still reaches the same Hono app via the step 2a fallback. - apps/vps/src/app.ts: added onShutdown(dispose) so the entry point can register effectWebHandler.dispose() to run before disposeRuntime() during SIGTERM/SIGINT. Sequenced inside the existing shutdown() closure (not a second process.on listener) so it can't race the existing process.exit(0)/exit(1) calls. Background forks (reminder loop, sitemap regeneration) are unaffected -- they run inside app.ts's initializeApp(), which the entry point still imports and awaits before building the handler. Verified: full apps/vps vitest suite (140/140, 15 files) passes unchanged, including the step 1b/2a blackbox suites exercising the new effectWebHandler end to end (health, a real API route, 404, dispose() after serving real requests). Not verified here: an actual OS-level SIGTERM against a running Bun.serve process -- no local env/SST resources available in this environment to boot the server standalone. The shutdown sequencing was reasoned through manually (see comments) but a real signal to a staged/dev instance is worth a manual check before this reaches prod, per the doc's Step 2 acceptance bar. --- apps/vps/src/app.ts | 10 ++++++++++ apps/vps/src/index.ts | 12 ++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/vps/src/app.ts b/apps/vps/src/app.ts index b6d6dfc9..f3ebe56c 100644 --- a/apps/vps/src/app.ts +++ b/apps/vps/src/app.ts @@ -135,11 +135,21 @@ const sitemapRegenerationEffect = regenerateSitemap.pipe( const mainEffect = setupRoutesEffect +// Registered by the entry point (src/index.ts) to dispose the Effect +// HttpRouter handler before the runtime shuts down. No-op until Step 2b wires +// the entry point to serve through it (docs/migration-effect-http-api.md). +let disposeWebHandler: (() => Promise) | undefined + +export const onShutdown = (dispose: () => Promise) => { + disposeWebHandler = dispose +} + const setupGracefulShutdown = () => { const shutdown = async (signal: string) => { console.log(`Graceful shutdown initiated via ${signal}`) try { + await disposeWebHandler?.() const { disposeRuntime } = await import('./runtime') await disposeRuntime() console.log('Runtime disposed successfully') diff --git a/apps/vps/src/index.ts b/apps/vps/src/index.ts index 9755dad9..32b681d8 100644 --- a/apps/vps/src/index.ts +++ b/apps/vps/src/index.ts @@ -1,14 +1,18 @@ export const localVPSPort = 3003 -const { default: app } = await import('./app') +const { default: app, onShutdown } = await import('./app') -// Step 2a (docs/migration-effect-http-api.md): proves the toWebHandler + fallback -// layer builds and serves identically to the Hono app. Not wired to Bun.serve yet. +// Step 2 (docs/migration-effect-http-api.md): the process now serves through +// this handler. It wildcards every request to the same Hono app unchanged -- +// app.ts still owns route setup, background forks, and its SIGTERM/SIGINT +// wiring. This is where the serving topology changes. const { createWebHandler } = await import('./http/routes') export const effectWebHandler = createWebHandler(app) +onShutdown(effectWebHandler.dispose) + export default { port: localVPSPort, - fetch: app.fetch, + fetch: effectWebHandler.handler, maxRequestBodySize: 1024 * 1024 * 1000 // 1GB }