Title: worker.exitedAfterDisconnect is set to `false` after worker.kill(), which doesn't comply with the documentation · Issue #51934 · nodejs/node · GitHub
Open Graph Title: worker.exitedAfterDisconnect is set to `false` after worker.kill(), which doesn't comply with the documentation · Issue #51934 · nodejs/node
X Title: worker.exitedAfterDisconnect is set to `false` after worker.kill(), which doesn't comply with the documentation · Issue #51934 · nodejs/node
Description: Version v18.16.0 (haven't check older version btw) Platform Linux 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 14:17:40 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Subsystem No response What steps will reproduce the bug? Run the...
Open Graph Description: Version v18.16.0 (haven't check older version btw) Platform Linux 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 14:17:40 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Subsystem No response Wh...
X Description: Version v18.16.0 (haven't check older version btw) Platform Linux 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 14:17:40 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Subsystem No respons...
Opengraph URL: https://github.com/nodejs/node/issues/51934
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"worker.exitedAfterDisconnect is set to `false` after worker.kill(), which doesn't comply with the documentation","articleBody":"### Version\r\n\r\nv18.16.0 (haven't check older version btw)\r\n\r\n### Platform\r\n\r\nLinux \u003cmy-machine-name> 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 14:17:40 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux\r\n\r\n### Subsystem\r\n\r\n_No response_\r\n\r\n### What steps will reproduce the bug?\r\n\r\n- Run the below code block using `node index.js` e.g.\r\n\r\n```const cluster = require(\"node:cluster\");\r\nconst http = require(\"node:http\");\r\nconst process = require(\"node:process\");\r\n\r\nif (cluster.isPrimary) {\r\n // Keep track of http requests\r\n let numReqs = 0;\r\n let inter = setInterval(() => {\r\n console.log(`numReqs = ${numReqs}`);\r\n }, 1000);\r\n\r\n // Count requests\r\n function messageHandler(msg) {\r\n if (msg.cmd && msg.cmd === \"notifyRequest\") {\r\n numReqs += 1;\r\n }\r\n }\r\n\r\n // Start workers and listen for messages containing notifyRequest\r\n const numCPUs = require(\"node:os\").availableParallelism();\r\n for (let i = 0; i \u003c 2; i++) {\r\n cluster.fork();\r\n }\r\n\r\n for (const id in cluster.workers) {\r\n cluster.workers[id].on(\"message\", messageHandler);\r\n }\r\n cluster.on(\"exit\", (worker, code, signal) => {\r\n console.log(\r\n `--------------EAD---------------${worker.exitedAfterDisconnect}-----`,\r\n );\r\n if (worker.exitedAfterDisconnect === true) {\r\n console.log(\"Oh, it was just voluntary – no need to worry\");\r\n } else {\r\n console.log(`-----------EXIT------------------${worker.process.pid}`);\r\n }\r\n });\r\n process.on(\"SIGINT\", async (signal) => {\r\n console.log(\"----------------SIGINT----------------------\");\r\n await killChildProcesses(cluster);\r\n console.log(\"-----------------DONE------------------\");\r\n process.exit(0);\r\n });\r\n} else {\r\n // Worker processes have a http server.\r\n const server = http\r\n .Server((req, res) => {\r\n res.writeHead(200);\r\n res.end(\"hello world\\n\");\r\n\r\n // Notify primary about the request\r\n process.send({ cmd: \"notifyRequest\" });\r\n })\r\n .listen(4000);\r\n process.on(\"SIGTERM\", (signal) => {\r\n console.log(\"----------------SIGTERM----------------------\");\r\n server.close(() => {\r\n console.log(\"----------------------CLOSED---------------------\");\r\n process.exit(0);\r\n });\r\n });\r\n}\r\n\r\nfunction killChildProcesses(cluster) {\r\n return new Promise((resolve) => {\r\n const aliveWorkers = Object.values(cluster.workers || {}).filter(\r\n (worker) => {\r\n return worker && !worker.isDead();\r\n },\r\n );\r\n\r\n if (aliveWorkers.length === 0) {\r\n resolve();\r\n return;\r\n }\r\n\r\n let workersAlive = aliveWorkers.length;\r\n\r\n const handleWorkerExit = () => {\r\n workersAlive--;\r\n if (workersAlive === 0) {\r\n resolve();\r\n }\r\n };\r\n\r\n aliveWorkers.forEach((worker) => {\r\n console.log(\"-----------KILLING-----------\");\r\n worker.on(\"exit\", handleWorkerExit);\r\n worker.kill();\r\n });\r\n });\r\n}\r\n\r\n```\r\n- find out the primary process number for this e.g. `ps -ef | grep index.js`\r\n- kill the process with `SIGINT` signal, i.e. `kill -SIGINT \u003cpid>`\r\n- the resulting console output is as below\r\n```\r\n----------------SIGINT----------------------\r\n-----------KILLING-----------\r\n-----------KILLING-----------\r\n----------------SIGTERM----------------------\r\n----------------SIGTERM----------------------\r\n----------------------CLOSED---------------------\r\n----------------------CLOSED---------------------\r\n--------------EAD---------------false--0---\r\n-----------EXIT------------------\u003cworker-1-pid>\r\n--------------EAD---------------false--0---\r\n-----------EXIT------------------\u003cworker-2-pid>\r\n-----------------DONE------------------\r\n\r\n```\r\n### How often does it reproduce? Is there a required condition?\r\n\r\nalways\r\n\r\n### What is the expected behavior? Why is that the expected behavior?\r\n\r\nThe expected behavior should be\r\n```\r\n----------------SIGINT----------------------\r\n-----------KILLING-----------\r\n-----------KILLING-----------\r\n----------------SIGTERM----------------------\r\n----------------SIGTERM----------------------\r\n----------------------CLOSED---------------------\r\n----------------------CLOSED---------------------\r\n--------------EAD---------------false--0---\r\nOh, it was just voluntary – no need to worry\r\n--------------EAD---------------false--0---\r\nOh, it was just voluntary – no need to worry\r\n-----------------DONE------------------\r\n```\r\n\r\n\r\n\r\n### What do you see instead?\r\n\r\nAs you can see the `worker.exitedAfterDisconnect` is not `true`, but the documentation (https://nodejs.org/api/cluster.html#workerexitedafterdisconnect) states that it should be true if you `kill()` or `disconnect()` the worker.\r\n\r\n\r\n\r\nAs you can the worker process exited with code 0, I don't understand which other way it can be exited with code 0 other that what the code is doing...\r\n\r\n### Additional information\r\n\r\n_No response_","author":{"url":"https://github.com/khaled4vokalz","@type":"Person","name":"khaled4vokalz"},"datePublished":"2024-03-01T11:47:07Z","url":"https://github.com/nodejs/node/issues/51934"}
| react-profiling | 0 |
| react-import-map | react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf |
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:b4b1854f-8579-f6e9-b4d4-849d4b0195d3 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E082:2F339D:971395:C8F9EE:6AED2EA8 |
| html-safe-nonce | 0dde45aeeac818d646dcd66f43505574bcedba05b7c511beac5ec2ea1ccc2556 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFMDgyOjJGMzM5RDo5NzEzOTU6QzhGOUVFOjZBRUQyRUE4IiwidmlzaXRvcl9pZCI6Ijg3NDMxNDgyMDYyMjk4OTI3NzYiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 40462b23ddbd53cdbb1655becaa65f5aa26c0e934b4091aefa9f9c8a2fe50d48 |
| hovercard-subject-tag | issue:2163230414 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/51934/issue_layout |
| twitter:image | https://opengraph.githubassets.com/ba8dbc6ecf92aae261f2b413d550c9ecd3b6e42b7f3360d14accf05fc8e39c33/nodejs/node/issues/51934 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/ba8dbc6ecf92aae261f2b413d550c9ecd3b6e42b7f3360d14accf05fc8e39c33/nodejs/node/issues/51934 |
| og:image:alt | Version v18.16.0 (haven't check older version btw) Platform Linux 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 14:17:40 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Subsystem No response Wh... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | khaled4vokalz |
| hostname | github.com |
| expected-hostname | github.com |
| None | e51d0b7b5ab34b1688c05b54c3ed17b8658b2fa9bca973a9c740683ccb12cf4a |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 59ebb7b901cc154ecc179a44f266fcf69f343b30 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
| react-app-name | issues |
Links:
Viewport: width=device-width