From d659ed6dbec914301555feeacc2a009e1889d0d1 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 2 Jun 2019 15:09:57 +0200 Subject: [PATCH] worker: refactor `worker.terminate()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the collaborator summit in Berlin, the behaviour of `worker.terminate()` was discussed. In particular, switching from a callback-based to a Promise-based API was suggested. While investigating that possibility later, it was discovered that `.terminate()` was unintentionally synchronous up until now (including calling its callback synchronously). Also, the topic of its stability has been brought up. I have performed two manual reviews of the native codebase for compatibility with `.terminate()`, and performed some manual fuzz testing with the test suite. At this point, bugs with `.terminate()` should, in my opinion, be treated like bugs in other Node.js features. (It is possible to make Node.js crash with `.terminate()` by messing with internals and/or built-in prototype objects, but that is already the case without `.terminate()` as well.) This commit: - Makes `.terminate()` an asynchronous operation. - Makes `.terminate()` return a `Promise`. - Runtime-deprecates passing a callback. - Removes a warning about its stability from the documentation. - Eliminates an unnecessary extra function from the C++ code. A possible alternative to returning a `Promise` would be to keep the method synchronous and just drop the callback. Generally, providing an asynchronous API does provide us with a bit more flexibility. Refs: https://github.com/nodejs/summit/issues/141 PR-URL: https://github.com/nodejs/node/pull/28021 Reviewed-By: Michaël Zasso Reviewed-By: Rich Trott Reviewed-By: Ben Noordhuis Reviewed-By: Tiancheng "Timothy" Gu Reviewed-By: Ruben Bridgewater Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell --- doc/api/deprecations.md | 15 +++++++++++ doc/api/worker_threads.md | 26 +++++++++---------- lib/internal/worker.js | 14 +++++++++- src/node_worker.cc | 7 +---- src/node_worker.h | 1 - test/parallel/test-worker-dns-terminate.js | 2 +- .../test-worker-nexttick-terminate.js | 8 +++++- 7 files changed, 50 insertions(+), 23 deletions(-) diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index e375e7a5ba12be..c5588bc257564a 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -2477,6 +2477,20 @@ The legacy HTTP parser, used by default in versions of Node.js prior to 12.0.0, is deprecated. This deprecation applies to users of the [`--http-parser=legacy`][] command-line flag. + +### DEP0XXX: worker.terminate() with callback + + +Type: Runtime + +Passing a callback to [`worker.terminate()`][] is deprecated. Use the returned +`Promise` instead, or a listener to the worker’s `'exit'` event. + [`--http-parser=legacy`]: cli.html#cli_http_parser_library [`--pending-deprecation`]: cli.html#cli_pending_deprecation [`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size @@ -2569,6 +2583,7 @@ is deprecated. This deprecation applies to users of the [`util.types`]: util.html#util_util_types [`util`]: util.html [`worker.exitedAfterDisconnect`]: cluster.html#cluster_worker_exitedafterdisconnect +[`worker.terminate()`]: worker_threads.html#worker_threads_worker_terminate [`zlib.bytesWritten`]: zlib.html#zlib_zlib_byteswritten [Legacy URL API]: url.html#url_legacy_url_api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 27d4fb2a6a62fb..39d948ccea7108 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -617,24 +617,23 @@ inside the worker thread. If `stdout: true` was not passed to the [`Worker`][] constructor, then data will be piped to the parent thread's [`process.stdout`][] stream. -### worker.terminate([callback]) +### worker.terminate() -* `callback` {Function} - * `err` {Error} - * `exitCode` {integer} +* Returns: {Promise} Stop all JavaScript execution in the worker thread as soon as possible. -`callback` is an optional function that is invoked once this operation is known -to have completed. - -**Warning**: Currently, not all code in the internals of Node.js is prepared to -expect termination at arbitrary points in time and may crash if it encounters -that condition. Consequently, only call `.terminate()` if it is known that the -Worker thread is not accessing Node.js core modules other than what is exposed -in the `worker` module. +Returns a Promise for the exit code that is fulfilled when the +[`'exit'` event][] is emitted. ### worker.threadId