oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
72.17k stars 2.58k forks source link

`SIGINT` handler is aborted when running file via package.json script #11400

Open jiftoo opened 1 month ago

jiftoo commented 1 month ago

What version of Bun is running?

1.1.10+5102a9443

What platform is your computer?

Microsoft Windows NT 10.0.19045.0 x64

What steps can reproduce the bug?

main.ts

function uptime(t: number) {
    return (process.uptime() - t).toFixed(1);
}

function sigintHandler(info: any) {
    const t = process.uptime();

    console.log("signal handler", info);

    setTimeout(() => (console.log("exit", uptime(t)), process.exit(0)), 1000);

    for (let i = 0; i < 100; i++) {
        console.log("looping", i);
    }

    console.log("done looping", uptime(t));
}

process.on("SIGINT", sigintHandler);

// keep running
setTimeout(() => {}, 10000);

package.json

// ...
"scripts": {
    "start": "bun main.ts"
},
// ...

What is the expected behavior?

The following printed to stdout on interrupt (Ctrl+C) when either of the following commands is ran: bun main.ts bun start

signal handler SIGINT
looping 0
...
looping 100
done looping 0.0
exit 1.0

What do you see instead?

When running bun main.ts, the output is correct. When running bun start, the output is either empty or truncated.

Additional information

Invoking SIGINT via process.emit("SIGINT", "SIGINT"); works correctly in either case. Does bun start kill the script it's running shortly after it receives an interrupt signal?

PhilBladen commented 1 month ago

I have also experienced this issue. Since the release of Bun 1.1 I have been trying to migrate from npm to bun, however this issue that running scripts in package.json does not allow the script SIGINT handler to execute is preventing me from doing so

schettn commented 1 week ago

@jiftoo Any updates?

schettn commented 1 week ago

I use the following:

 let currentProc: Subprocess | null = null

  let serve = async () => {
    if (currentProc) {
      currentProc.kill()

      await currentProc.exited
    }

    currentProc = Bun.spawn({
      cmd: [
        'bun',
        'run',
        // 'pylon-server',  // DOES NOT WORK
        '/Users/schettn/Documents/pylon/node_modules/.bin/pylon-server', // WORKS
        '--port',
        options.port
      ],
      stdout: 'inherit',
      onExit: () => {
        console.log('Process exited')
      }
    })
  }

  await serve()

  setInterval(async () => {
    console.log('Rebuilding')
    await serve()
    console.log('Rebuilt')
  }, 10000)

The problem is that when I want to spawn bun run pylon-server the PID is not from /Users/schettn/Documents/pylon/node_modules/.bin/pylon-server'. Instead thePIDofcurrentProc`.

Therefore I cannot call currentProc.kill() and restart my server.