How to abort Deno.serve via request right after the respective response was sent?
My current workaround is a 1s sleep before aborting the AbortController. I've tried queueMicrotask, but it seems like the response is not sent via the main thread.
Here is my workaround:
//example.ts
//deno run --allow-net=127.0.0.1 example.ts
const port = 3000;
const hostname = "127.0.0.1";
const ac = new AbortController();
const signal = ac.signal;
let isShuttingDown = false;
const server = Deno.serve(
{ port, hostname, signal },
(req: Request, _info: Deno.ServeHandlerInfo) => {
if (isShuttingDown) {
return new Response("Server is shutting down!", { status: 503 });
}
const url = new URL(req.url);
if (
url.pathname === "/shutdown"
) {
isShuttingDown = true;
// queueMicrotask(()=>{ //does not run after response is sent
// ac.abort();
// });
setTimeout(() => {
ac.abort();
}, 1000); //give client time to receive response
return new Response(null, { status: 202 });
}
return new Response("hello");
},
);
await server.finished;
console.log("server stopped");
Is there a better way than waiting with a long enough timeout?
In Deno v1.38, an unstable method
shtudownwas added to the classDeno.HttpServerto facilitate graceful shutdown.I haven't yet reviewed the source code implementation (so maybe I'm missing something) but using it inside a server handler function currently still appears to require a delay. Perhaps the implementation prevents any new responses from being sent immediately after invocation — the documentation does not make this clear.
In short, you can gracefully shutdown the server in your request handler callback function just before returning the response, like this:
Here's a complete reproducible example:
server.ts:Terminal: