mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
feat(ext/http): ref/unref for server (#19197)
Add `ref` and `unref` to return value from `Deno.serve`. Unblocks #3326.
This commit is contained in:
parent
af72a9c657
commit
7f5290b694
3 changed files with 54 additions and 2 deletions
|
@ -10,6 +10,7 @@ import {
|
||||||
assertThrows,
|
assertThrows,
|
||||||
Deferred,
|
Deferred,
|
||||||
deferred,
|
deferred,
|
||||||
|
execCode,
|
||||||
fail,
|
fail,
|
||||||
} from "./test_util.ts";
|
} from "./test_util.ts";
|
||||||
|
|
||||||
|
@ -56,6 +57,21 @@ Deno.test(async function httpServerShutsDownPortBeforeResolving() {
|
||||||
listener!.close();
|
listener!.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
{ permissions: { read: true, run: true } },
|
||||||
|
async function httpServerUnref() {
|
||||||
|
const [statusCode, _output] = await execCode(`
|
||||||
|
async function main() {
|
||||||
|
const server = Deno.serve({ port: 4501, handler: () => null });
|
||||||
|
server.unref();
|
||||||
|
await server.finished; // This doesn't block the program from exiting
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`);
|
||||||
|
assertEquals(statusCode, 0);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Deno.test(async function httpServerCanResolveHostnames() {
|
Deno.test(async function httpServerCanResolveHostnames() {
|
||||||
const ac = new AbortController();
|
const ac = new AbortController();
|
||||||
const listeningPromise = deferred();
|
const listeningPromise = deferred();
|
||||||
|
|
12
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
12
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
|
@ -1312,7 +1312,19 @@ declare namespace Deno {
|
||||||
* the signal passed to {@linkcode ServeOptions.signal}.
|
* the signal passed to {@linkcode ServeOptions.signal}.
|
||||||
*/
|
*/
|
||||||
finished: Promise<void>;
|
finished: Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the server block the event loop from finishing.
|
||||||
|
*
|
||||||
|
* Note: the server blocks the event loop from finishing by default.
|
||||||
|
* This method is only meaningful after `.unref()` is called.
|
||||||
|
*/
|
||||||
|
ref(): void;
|
||||||
|
|
||||||
|
/** Make the server not block the event loop from finishing. */
|
||||||
|
unref(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** **UNSTABLE**: New API, yet to be vetted.
|
/** **UNSTABLE**: New API, yet to be vetted.
|
||||||
*
|
*
|
||||||
* Serves HTTP requests with the given handler.
|
* Serves HTTP requests with the given handler.
|
||||||
|
|
|
@ -43,6 +43,7 @@ const {
|
||||||
SetPrototypeAdd,
|
SetPrototypeAdd,
|
||||||
SetPrototypeDelete,
|
SetPrototypeDelete,
|
||||||
Symbol,
|
Symbol,
|
||||||
|
SymbolFor,
|
||||||
TypeError,
|
TypeError,
|
||||||
Uint8Array,
|
Uint8Array,
|
||||||
Uint8ArrayPrototype,
|
Uint8ArrayPrototype,
|
||||||
|
@ -660,13 +661,22 @@ function serve(arg1, arg2) {
|
||||||
|
|
||||||
onListen({ port: listenOpts.port });
|
onListen({ port: listenOpts.port });
|
||||||
|
|
||||||
|
let ref = true;
|
||||||
|
let currentPromise = null;
|
||||||
|
const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId");
|
||||||
|
|
||||||
// Run the server
|
// Run the server
|
||||||
const finished = (async () => {
|
const finished = (async () => {
|
||||||
while (true) {
|
while (true) {
|
||||||
const rid = context.serverRid;
|
const rid = context.serverRid;
|
||||||
let req;
|
let req;
|
||||||
try {
|
try {
|
||||||
req = await op_http_wait(rid);
|
currentPromise = op_http_wait(rid);
|
||||||
|
if (!ref) {
|
||||||
|
core.unrefOp(currentPromise[promiseIdSymbol]);
|
||||||
|
}
|
||||||
|
req = await currentPromise;
|
||||||
|
currentPromise = null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) {
|
if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) {
|
||||||
break;
|
break;
|
||||||
|
@ -691,7 +701,21 @@ function serve(arg1, arg2) {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return { finished };
|
return {
|
||||||
|
finished,
|
||||||
|
ref() {
|
||||||
|
ref = true;
|
||||||
|
if (currentPromise) {
|
||||||
|
core.refOp(currentPromise[promiseIdSymbol]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unref() {
|
||||||
|
ref = false;
|
||||||
|
if (currentPromise) {
|
||||||
|
core.unrefOp(currentPromise[promiseIdSymbol]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internals.addTrailers = addTrailers;
|
internals.addTrailers = addTrailers;
|
||||||
|
|
Loading…
Add table
Reference in a new issue