diff --git a/lib/main.ts b/lib/main.ts index 7c024b126..83b965b0c 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -67,6 +67,10 @@ export async function main( // this function in the exit context so it can be called anywhere. yield* ExitContext.set(resolve); + // this will hold the event loop and prevent runtimes such as + // Node and Deno from exiting prematurely. + let interval = setInterval(() => {}, Math.pow(2, 30)); + try { let interrupt = () => resolve({ status: 130, signal: "SIGINT" }); yield* withHost({ @@ -105,6 +109,8 @@ export async function main( yield* exit(0); } catch (error) { resolve({ status: 1, error }); + } finally { + clearInterval(interval); } }) ); diff --git a/test/main.test.ts b/test/main.test.ts index 45e3f300b..8ac672bd0 100644 --- a/test/main.test.ts +++ b/test/main.test.ts @@ -83,6 +83,25 @@ describe("main", () => { expect(status.code).toEqual(1); }); }); + + it("works even if suspend is the only operation", async () => { + await run(function* () { + let process = yield* useCommand("deno", { + stdout: "piped", + args: ["run", "test/main/just.suspend.ts"], + }); + let stdout = yield* buffer(process.stdout); + yield* detect(stdout, "started"); + + process.kill("SIGINT"); + + let status = yield* process.status; + + expect(status.code).toBe(130); + + yield* detect(stdout, "gracefully stopped"); + }); + }); }); import type { Operation } from "../lib/types.ts"; diff --git a/test/main/just.suspend.ts b/test/main/just.suspend.ts new file mode 100644 index 000000000..0013ad646 --- /dev/null +++ b/test/main/just.suspend.ts @@ -0,0 +1,11 @@ +import { suspend } from "../../lib/instructions.ts"; +import { main } from "../../lib/main.ts"; + +await main(function* () { + console.log("started"); + try { + yield* suspend(); + } finally { + console.log("gracefully stopped"); + } +});