clinic doctor issues running worker thread test
Attempting to run the following in Node.js 13.11.0
const {
Worker,
isMainThread,
} = require('worker_threads');
if (isMainThread) {
for (let n = 0; n < 100; n++) {
new Worker(__filename);
}
} else {
const m = [...new Array(1000)];
JSON.stringify(m);
}
Any number of threads causes the same failure. See gist: https://gist.github.com/jasnell/a8e584452e5ac4da6a1f8b6f90e8bf28
Using clinic v5.0.0 (clinic doctor -- node t.js)
Error:
To generate the report press: Ctrl + C
[ ] Analysing dataundefined:20
if (!found0 || !found1 || !found2 || !found3 || !found4) throw new Error("Decoded message is not valid")
^
Error: Decoded message is not valid
at Object.decode (eval at line.toFunction (/home/james/.nvm/versions/node/v13.11.0/lib/node_modules/clinic/node_modules/generate-function/index.js:172:21), <anonymous>:20:70)
at ProcessStatDecoder._transform (/home/james/.nvm/versions/node/v13.11.0/lib/node_modules/clinic/node_modules/@nearform/doctor/format/abstract-decoder.js:42:31)
at ProcessStatDecoder.Transform._read (_stream_transform.js:191:10)
at ProcessStatDecoder.Transform._write (_stream_transform.js:179:12)
at doWrite (_stream_writable.js:392:12)
at writeOrBuffer (_stream_writable.js:374:5)
at ProcessStatDecoder.Writable.write (_stream_writable.js:314:12)
at ReadStream.ondata (_stream_readable.js:708:22)
at ReadStream.emit (events.js:315:20)
at addChunk (_stream_readable.js:297:12)
The issue appears to have been introduced between Node.js 13.9.0 and Node.js 13.10.0. With 13.9.0 no error is thrown. Under the 13.9.0 profile trace no data collected for the processstat file, likely because the test does not run long enough to collect data. Under 13.10.0 and higher tho, the processstat file is not empty.
The issue appears to be a race condition for worker threads... essentially, every worker has it's own copy of the sampler code which ends up concurrently writing samples into the same file causing it to be corrupted. The fix should be to redirect worker thread samples into their own files, which we can then process separately.
Refs: https://github.com/nearform/node-clinic-common/pull/22