I played around with subscriptions by using SSE and noticed that my EventEmitter was hitting the max listener limit. It seems that the opts.signal is never signalling the abort of the request. After patching the createNuxtApiHandler and using a custom AbortController I managed to clean up the closed/aborted connections most of the time. The issue seems to be that toWebRequest is not managing the AbortSignal properly. Here is my "working" example:
// Example router
import { EventEmitter, on } from "node:events";
import { z } from "zod";
import { authedProcedure, router } from "../trpc";
const ee = new EventEmitter();
export const appRouter = router({
chat: authedProcedure.input(z.void()).subscription(async function* (opts) {
console.log("listeners: ", ee.listenerCount("add") + 1);
for await (const [data] of on(ee, "add", {
signal: opts.signal, // Sometimes this signal is not aborted
})) {
yield data;
}
}),
});
// Patched createNuxtApiHandler
// ...
if (event.method === "POST") {
req.body = await readBody(event);
}
// We create our own AbortController and attach it to the Request
const abortController = new AbortController();
const reqFromEvent = new Request(toWebRequest(event), {
signal: abortController.signal
});
req.on("close", () => {
abortController.abort();
})
const httpResponse = await resolveResponse({
...opts,
req: reqFromEvent,
error: null,
createContext,
path,
onError(o) {
opts.onError?.({
...o,
req
});
}
});
This seems to somewhat fix the issue but there is still a leak when i spam reload the browser. Any ideas on how to fix this?
Environment
Node: v20.15.0
Browsers:
Chrome: 131.0.6778.265
Safari: 18.2
npmPackages
@trpc/server@11.0.0-rc.700
@trpc/client@11.0.0-rc.700
trpc-nuxt@0.11.1-next.1
I played around with subscriptions by using SSE and noticed that my EventEmitter was hitting the max listener limit. It seems that the
opts.signalis never signalling the abort of the request. After patching the createNuxtApiHandler and using a custom AbortController I managed to clean up the closed/aborted connections most of the time. The issue seems to be thattoWebRequestis not managing the AbortSignal properly. Here is my "working" example:This seems to somewhat fix the issue but there is still a leak when i spam reload the browser. Any ideas on how to fix this?
Environment