diff options
Diffstat (limited to 'ext/http')
-rw-r--r-- | ext/http/00_serve.js | 22 | ||||
-rw-r--r-- | ext/http/01_http.js | 27 |
2 files changed, 37 insertions, 12 deletions
diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index 17a67814b..b99f28c0f 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -36,6 +36,7 @@ import { } from "ext:deno_web/06_streams.js"; import { listen, listenOptionApiName, TcpConn } from "ext:deno_net/01_net.js"; import { listenTls } from "ext:deno_net/02_tls.js"; +import { SymbolAsyncDispose } from "ext:deno_web/00_infra.js"; const { ArrayPrototypePush, ObjectHasOwn, @@ -343,6 +344,7 @@ class CallbackContext { fallbackHost; serverRid; closed; + /** @type {Promise<void> | undefined} */ closing; listener; @@ -671,22 +673,25 @@ function serveHttpOn(context, callback) { PromisePrototypeCatch(callback(req), promiseErrorHandler); } - if (!context.closed && !context.closing) { - context.closed = true; - await op_http_close(rid, false); + if (!context.closing && !context.closed) { + context.closing = op_http_close(rid, false); context.close(); } + + await context.closing; + context.close(); + context.closed = true; })(); return { finished, async shutdown() { - if (!context.closed && !context.closing) { + if (!context.closing && !context.closed) { // Shut this HTTP server down gracefully - context.closing = true; - await op_http_close(context.serverRid, true); - context.closed = true; + context.closing = op_http_close(context.serverRid, true); } + await context.closing; + context.closed = true; }, ref() { ref = true; @@ -700,6 +705,9 @@ function serveHttpOn(context, callback) { core.unrefOp(currentPromise[promiseIdSymbol]); } }, + [SymbolAsyncDispose]() { + return this.shutdown(); + }, }; } diff --git a/ext/http/01_http.js b/ext/http/01_http.js index 705e616e4..cfe0f710e 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -44,6 +44,7 @@ import { ReadableStreamPrototype, } from "ext:deno_web/06_streams.js"; import { serve } from "ext:deno_http/00_serve.js"; +import { SymbolDispose } from "ext:deno_web/00_infra.js"; const { ArrayPrototypeIncludes, ArrayPrototypeMap, @@ -69,6 +70,9 @@ const { const connErrorSymbol = Symbol("connError"); const _deferred = Symbol("upgradeHttpDeferred"); +/** @type {(self: HttpConn, rid: number) => boolean} */ +let deleteManagedResource; + class HttpConn { #rid = 0; #closed = false; @@ -79,7 +83,12 @@ class HttpConn { // that were created during lifecycle of this request. // When the connection is closed these resources should be closed // as well. - managedResources = new SafeSet(); + #managedResources = new SafeSet(); + + static { + deleteManagedResource = (self, rid) => + SetPrototypeDelete(self.#managedResources, rid); + } constructor(rid, remoteAddr, localAddr) { this.#rid = rid; @@ -123,7 +132,7 @@ class HttpConn { } const { 0: streamRid, 1: method, 2: url } = nextRequest; - SetPrototypeAdd(this.managedResources, streamRid); + SetPrototypeAdd(this.#managedResources, streamRid); /** @type {ReadableStream<Uint8Array> | undefined} */ let body = null; @@ -167,13 +176,21 @@ class HttpConn { if (!this.#closed) { this.#closed = true; core.close(this.#rid); - for (const rid of new SafeSetIterator(this.managedResources)) { - SetPrototypeDelete(this.managedResources, rid); + for (const rid of new SafeSetIterator(this.#managedResources)) { + SetPrototypeDelete(this.#managedResources, rid); core.close(rid); } } } + [SymbolDispose]() { + core.tryClose(this.#rid); + for (const rid of new SafeSetIterator(this.#managedResources)) { + SetPrototypeDelete(this.#managedResources, rid); + core.tryClose(rid); + } + } + [SymbolAsyncIterator]() { // deno-lint-ignore no-this-alias const httpConn = this; @@ -395,7 +412,7 @@ function createRespondWith( abortController.abort(error); throw error; } finally { - if (SetPrototypeDelete(httpConn.managedResources, streamRid)) { + if (deleteManagedResource(httpConn, streamRid)) { core.close(streamRid); } } |