feat(queue): add typed application queue lifecycle
Quality / quality (ubuntu-latest) (push) Failing after 10m55s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-08-23 09:22:05 +05:30
1 parent 9332522614
commit 9377a69d88
17 files changed
+667 -13

No files matched your search

+27
View File
@@ -909,6 +909,7 @@ export interface Ws {
export interface Handlers {
fetch(req: Request, server: UpgradeServer): Promise<Response | undefined>;
shutdown(): Promise<void>;
websocket: {
open(ws: Ws): void;
message(ws: Ws, message: string | Uint8Array): void;
@@ -985,6 +986,27 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
}
return servicesPromise;
};
type QueueModule = { start(): void; shutdown(options?: { force?: boolean }): Promise<void> };
let queuesPromise: Promise<QueueModule[]> | undefined;
const loadQueues = (): Promise<QueueModule[]> => {
queuesPromise ??= (async () => {
const queues: QueueModule[] = [];
for (const entry of router.queues ?? []) {
const imported = await loadModule(entry.file);
const queue = imported.default as QueueModule | undefined;
if (!queue || typeof queue.start !== "function" || typeof queue.shutdown !== "function") {
throw new Error(`Queue ${entry.file} must default-export defineQueue(...)`);
}
queue.start();
queues.push(queue);
}
return queues;
})().catch((error) => {
queuesPromise = undefined;
throw error;
});
return queuesPromise;
};
// Server-side realtime room manager (shared by every `defineRoom` connection).
const realtime = createRealtimeRegistry();
@@ -1041,6 +1063,7 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
};
async function fetchHandler(req: Request, server: UpgradeServer): Promise<Response | undefined> {
await loadQueues();
// Behind a trusted proxy (nginx / gateway), honor X-Forwarded-Proto/Host so
// ctx.url reflects the external HTTPS scheme — makes CSRF/session cookies Secure.
const url = resolveRequestUrl(req, deps.security?.trustProxy);
@@ -2321,6 +2344,10 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
return {
fetch: fetchHandler,
async shutdown() {
const queues = await queuesPromise?.catch(() => []);
await Promise.allSettled((queues ?? []).map((queue) => queue.shutdown()));
},
websocket: {
open(ws) {
if (ws.data?.kind === "hmr") hub?.add(ws);