Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve graceful exit #714

Merged
merged 2 commits into from
Jan 23, 2024
Merged

Improve graceful exit #714

merged 2 commits into from
Jan 23, 2024

Conversation

ehmicky
Copy link
Collaborator

@ehmicky ehmicky commented Jan 22, 2024

Fixes #511.

This extends graceful exits to the following termination methods:

  • signal option
  • cleanup option
  • timeout option
  • maxBuffer option
  • stream errors
  • childProcess.on('error') event

This moves the forceKillAfterTimeout option from the .kill() method to the top-level options instead.

/**
Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal), except if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`. Note that this graceful termination does not work on Windows, because Windows [doesn't support signals](https://nodejs.org/api/process.html#process_signal_events) (`SIGKILL` and `SIGTERM` has the same effect of force-killing the process immediately.) If you want to achieve graceful termination on Windows, you have to use other means, such as [`taskkill`](https://github.com/sindresorhus/taskkill).
*/
kill(signal?: string, options?: KillOptions): void;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process.kill() now has the same signature as in core Node.js.

The only difference is the graceful exit behavior, which we document with the forceKillAfterTimeout option, so there's no need to document process.kill() here anymore.

forceKillAfterTimeout: 2000
});
}, 1000);
```
Copy link
Collaborator Author

@ehmicky ehmicky Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The graceful exit behavior happens by default. It's probably not critical to add an example for it anymore. This leaves more room for other more useful examples.

@@ -6,6 +6,7 @@ process.on('SIGTERM', () => {
});

process.send('');
console.log('.');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for the maxBuffer test.

readme.md Show resolved Hide resolved
@ehmicky ehmicky changed the title Move forceKillAfterTimeout options to top-level Improve graceful exit Jan 22, 2024
@ehmicky ehmicky force-pushed the graceful-exit branch 4 times, most recently from 88179ee to 175c0de Compare January 22, 2024 21:29
await pSetTimeout(timeout, undefined, {ref: false});
kill('SIGKILL');
try {
await setTimeout(forceKillAfterTimeout, undefined, {signal: controller.signal});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The controller is aborted when the child process exits (successfully or not). When this happens, setTimeout() throws, hence the empty catch block.

@@ -43,20 +45,18 @@ const getForceKillAfterTimeout = (signal, forceKillAfterTimeout, killResult) =>
};

const killAfterTimeout = async ({spawned, timeout, killSignal, context, controller}) => {
await pSetTimeout(timeout, undefined, {ref: false, signal: controller.signal});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ref: false not needed thanks to the controller.

index.d.ts Outdated Show resolved Hide resolved
readme.md Outdated
@@ -50,7 +50,7 @@ This package improves [`child_process`](https://nodejs.org/api/child_process.htm
- Redirect [`stdin`](#stdin)/[`stdout`](#stdout-1)/[`stderr`](#stderr-1) from/to files, streams, iterables, strings, `Uint8Array` or [objects](docs/transform.md#object-mode).
- [Transform](docs/transform.md) `stdin`/`stdout`/`stderr` with simple functions.
- Iterate over [each text line](docs/transform.md#binary-data) output by the process.
- [Graceful termination](#optionsforcekillaftertimeout).
- [Graceful termination](#forcekillaftertimeout).
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use a better word than "graceful" as it can be misunderstood.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7312082

readme.md Outdated Show resolved Hide resolved
@sindresorhus sindresorhus merged commit 5eeaab5 into main Jan 23, 2024
12 checks passed
@sindresorhus sindresorhus deleted the graceful-exit branch January 23, 2024 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow the ‘forceKillAfterTimeout’ option to be passed to ‘.cancel()’
2 participants