mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
feat(runtime/spawn): add AbortSignal
support (#14538)
This commit is contained in:
parent
e3f4b02f48
commit
b67f874b3f
3 changed files with 43 additions and 1 deletions
6
cli/dts/lib.deno.unstable.d.ts
vendored
6
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -1346,6 +1346,12 @@ declare namespace Deno {
|
|||
uid?: number;
|
||||
/** Similar to `uid`, but sets the group ID of the child process. */
|
||||
gid?: number;
|
||||
/**
|
||||
* An AbortSignal that allows closing the process using the corresponding
|
||||
* AbortController by sending the process a SIGTERM signal.
|
||||
* Not Supported by execSync.
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
|
||||
/** Defaults to "null". */
|
||||
stdin?: "piped" | "inherit" | "null";
|
||||
|
|
|
@ -248,6 +248,32 @@ Deno.test(
|
|||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { run: true, read: true } },
|
||||
async function spawnAbort() {
|
||||
const ac = new AbortController();
|
||||
const child = Deno.spawnChild(Deno.execPath(), {
|
||||
args: [
|
||||
"eval",
|
||||
"setTimeout(console.log, 1e8)",
|
||||
],
|
||||
signal: ac.signal,
|
||||
stdout: "null",
|
||||
stderr: "null",
|
||||
});
|
||||
queueMicrotask(() => ac.abort());
|
||||
const status = await child.status;
|
||||
assertEquals(status.success, false);
|
||||
if (Deno.build.os === "windows") {
|
||||
assertEquals(status.code, 1);
|
||||
assertEquals(status.signal, null);
|
||||
} else {
|
||||
assertEquals(status.success, false);
|
||||
assertEquals(status.code, 143);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true, run: false } },
|
||||
async function spawnPermissions() {
|
|
@ -5,6 +5,7 @@
|
|||
const core = window.Deno.core;
|
||||
const { pathFromURL } = window.__bootstrap.util;
|
||||
const { illegalConstructorKey } = window.__bootstrap.webUtil;
|
||||
const { add, remove } = window.__bootstrap.abortSignal;
|
||||
const {
|
||||
ArrayPrototypeMap,
|
||||
ObjectEntries,
|
||||
|
@ -26,6 +27,7 @@
|
|||
stdin = "null",
|
||||
stdout = "piped",
|
||||
stderr = "piped",
|
||||
signal = undefined,
|
||||
} = {}) {
|
||||
const child = core.opSync("op_spawn_child", {
|
||||
cmd: pathFromURL(command),
|
||||
|
@ -39,7 +41,10 @@
|
|||
stdout,
|
||||
stderr,
|
||||
});
|
||||
return new Child(illegalConstructorKey, child);
|
||||
return new Child(illegalConstructorKey, {
|
||||
...child,
|
||||
signal,
|
||||
});
|
||||
}
|
||||
|
||||
async function collectOutput(readableStream) {
|
||||
|
@ -91,6 +96,7 @@
|
|||
}
|
||||
|
||||
constructor(key = null, {
|
||||
signal,
|
||||
rid,
|
||||
pid,
|
||||
stdinRid,
|
||||
|
@ -119,8 +125,12 @@
|
|||
this.#stderr = readableStreamForRid(stderrRid);
|
||||
}
|
||||
|
||||
const onAbort = () => this.kill("SIGTERM");
|
||||
signal?.[add](onAbort);
|
||||
|
||||
this.#status = core.opAsync("op_spawn_wait", this.#rid).then((res) => {
|
||||
this.#rid = null;
|
||||
signal?.[remove](onAbort);
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue