mirror of
https://github.com/denoland/std.git
synced 2024-11-22 04:59:05 +00:00
fix(http): remove unnecessary delay when closing server (#2732)
This commit is contained in:
parent
7f7583139e
commit
385511bc43
@ -57,6 +57,7 @@ export class Server {
|
||||
#handler: Handler;
|
||||
#closed = false;
|
||||
#listeners: Set<Deno.Listener> = new Set();
|
||||
#acceptBackoffDelayAbortController = new AbortController();
|
||||
#httpConnections: Set<Deno.HttpConn> = new Set();
|
||||
#onError: (error: unknown) => Response | Promise<Response>;
|
||||
|
||||
@ -263,6 +264,8 @@ export class Server {
|
||||
|
||||
this.#listeners.clear();
|
||||
|
||||
this.#acceptBackoffDelayAbortController.abort();
|
||||
|
||||
for (const httpConn of this.#httpConnections) {
|
||||
this.#closeHttpConn(httpConn);
|
||||
}
|
||||
@ -384,7 +387,16 @@ export class Server {
|
||||
acceptBackoffDelay = MAX_ACCEPT_BACKOFF_DELAY;
|
||||
}
|
||||
|
||||
await delay(acceptBackoffDelay);
|
||||
try {
|
||||
await delay(acceptBackoffDelay, {
|
||||
signal: this.#acceptBackoffDelayAbortController.signal,
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
// The backoff delay timer is aborted when closing the server.
|
||||
if (!(err instanceof DOMException && err.name === "AbortError")) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -991,6 +991,44 @@ Deno.test(
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test("Server should not leak async ops when closed", () => {
|
||||
const hostname = "127.0.0.1";
|
||||
const port = 4505;
|
||||
const handler = () => new Response();
|
||||
const server = new Server({ port, hostname, handler });
|
||||
server.listenAndServe();
|
||||
server.close();
|
||||
// Otherwise, the test would fail with: AssertionError: Test case is leaking async ops.
|
||||
});
|
||||
|
||||
Deno.test("Server should abort accept backoff delay when closing", async () => {
|
||||
const hostname = "127.0.0.1";
|
||||
const port = 4505;
|
||||
const handler = () => new Response();
|
||||
|
||||
const rejectionError = new Deno.errors.NotConnected(
|
||||
"test-socket-closed-error",
|
||||
);
|
||||
const rejectionCount = 1;
|
||||
const conn = createMockConn();
|
||||
|
||||
const listener = new MockListener({
|
||||
conn,
|
||||
rejectionError,
|
||||
rejectionCount,
|
||||
});
|
||||
|
||||
const server = new Server({ port, hostname, handler });
|
||||
server.serve(listener);
|
||||
|
||||
// Wait until the connection is rejected and the backoff delay starts.
|
||||
await delay(0);
|
||||
|
||||
// Close the server, this should end the test without still having an active timer that would trigger an
|
||||
// AssertionError: Test case is leaking async ops.
|
||||
server.close();
|
||||
});
|
||||
|
||||
Deno.test("Server should reject if the listener throws an unexpected error accepting a connection", async () => {
|
||||
const conn = createMockConn();
|
||||
const rejectionError = new Error("test-unexpected-error");
|
||||
|
Loading…
Reference in New Issue
Block a user