Skip to content

Commit

Permalink
fix: bun and node server respect abort signal
Browse files Browse the repository at this point in the history
Fixes #651
  • Loading branch information
kitsonk committed Apr 19, 2024
1 parent bbd2111 commit 662d1fe
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
26 changes: 26 additions & 0 deletions http_server_bun.test.ts
Expand Up @@ -125,3 +125,29 @@ Deno.test({
teardown();
},
});

Deno.test({
name: "bun server closes on abort signal",
// this is working but there is some sort of hanging promise somewhere I can't
// narrow down at the moment
ignore: true,
async fn() {
setup([new Request(new URL("http://localhost:8080/"))]);
const controller = new AbortController();
const { signal } = controller;
const server = new Server(createMockApp(), { port: 8080, signal });
const listener = await server.listen();
assertEquals(listener, { addr: { hostname: "localhost", port: 8080 } });
assert(currentServer);
for await (const req of server) {
assert(!req.body);
assertEquals(req.url, "/");
await req.respond(new Response("hello world"));
}
controller.abort();
await currentServer.runPromise;
assertEquals(currentServer.stoppedCount, 1);
assertEquals(currentServer.responses.length, 1);
teardown();
},
});
10 changes: 7 additions & 3 deletions http_server_bun.ts
Expand Up @@ -166,13 +166,13 @@ class BunRequest implements ServerRequest {
/** An implementation of the oak server abstraction for handling requests on
* Bun using the built in Bun http server. */
export class Server implements OakServer<BunRequest> {
#options: Omit<ServeOptions | ServeTlsOptions, "signal">;
#options: ServeOptions | ServeTlsOptions;
#server?: BunServer;
#stream?: ReadableStream<BunRequest>;

constructor(
_app: Application,
options: Omit<ServeOptions | ServeTlsOptions, "signal">,
options: ServeOptions | ServeTlsOptions,
) {
this.#options = options;
}
Expand All @@ -187,7 +187,7 @@ export class Server implements OakServer<BunRequest> {
if (this.#server) {
throw new Error("Server already listening.");
}
const { onListen, hostname, port } = this.#options;
const { onListen, hostname, port, signal } = this.#options;
const tls = isServeTlsOptions(this.#options)
? { key: this.#options.key, cert: this.#options.cert }
: undefined;
Expand All @@ -204,6 +204,10 @@ export class Server implements OakServer<BunRequest> {
port,
tls,
});
signal?.addEventListener("abort", () => {
controller.close();
this.close();
}, { once: true });
{
const { hostname, port } = this.#server;
if (onListen) {
Expand Down
22 changes: 18 additions & 4 deletions http_server_node.ts
Expand Up @@ -6,7 +6,13 @@
* @module
*/

import type { Listener, OakServer, ServerRequest } from "./types.ts";
import type {
Listener,
OakServer,
ServeOptions,
ServerRequest,
ServeTlsOptions,
} from "./types.ts";
import { createPromiseWithResolvers } from "./utils/create_promise_with_resolvers.ts";

// There are quite a few differences between Deno's `std/node/http` and the
Expand Down Expand Up @@ -155,10 +161,13 @@ export class Server implements OakServer<NodeRequest> {

constructor(
_app: unknown,
options: Deno.ListenOptions | Deno.ListenTlsOptions,
options: ServeOptions | ServeTlsOptions,
) {
this.#host = options.hostname ?? "127.0.0.1";
this.#port = options.port;
this.#port = options.port ?? 80;
options.signal?.addEventListener("abort", () => {
this.close();
}, { once: true });
}

close(): void {
Expand All @@ -169,11 +178,16 @@ export class Server implements OakServer<NodeRequest> {
const { createServer } = await import("node:http");
let server: NodeHttpServer;
this.#requestStream = new ReadableStream({
start(controller) {
start: (controller) => {
server = createServer((req, res) => {
// deno-lint-ignore no-explicit-any
controller.enqueue(new NodeRequest(req as any, res as any));
});
this.#abortController.signal.addEventListener(
"abort",
() => controller.close(),
{ once: true },
);
},
});
server!.listen({
Expand Down

0 comments on commit 662d1fe

Please sign in to comment.