Description
Version
20.3.0
Platform
Linux *** 6.5.0-15-generic #15~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 12 18:54:30 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
No response
What steps will reproduce the bug?
server.js
const http = require('http');
const cluster = require('cluster');
cluster.setupPrimary({
exec: 'worker.js',
//execArgv: ['--inspect'],
//inspectPort: 12000,
args: [],
windowsHide: true
});
const worker = cluster.fork();
const server = http.createServer((request, response) => {
let data = '';
request.on('data', (chunk) => {
data += chunk.toString();
});
request.on('end', () => {
if (request.method === 'POST') {
worker.send({ type: 'request', data: JSON.parse(data) }, response.socket);
} else {
response.end('ok');
}
});
});
server.listen(3000);
worker.js
process.on('message', (message, socket) => {
if (message.type !== 'request' || socket == null) {
return;
}
const data = JSON.stringify({
result: {
isWorker: true,
inputData: message.data
}
});
socket.write(`HTTP/1.1 200 OK\r\n`);
socket.write(`Server: node-worker\r\n`);
socket.write(`Content-Length: ${Buffer.byteLength(data)}\r\n`);
socket.write(`Content-Type: application/json\r\n`);
socket.write(`Connection: close\r\n`);
socket.write(`\r\n`);
socket.end(data);
});
Start node server
node server.js
Open a browser, navigate to http://localhost:3000, open devtools, and execute the following snippet:
const totalExecutions = 100;
let numberOfExecutions = totalExecutions;
let processed = 0;
while(--numberOfExecutions >= 0) {
doFetch();
}
function doFetch() {
const data = {
action: 'test',
data: {
foo: 'bar'
}
}
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
fetch('http://localhost:3000', fetchOptions).then(response=>{
return response.json()
}).then((result)=>{
onProcessed(null, result);
}).catch(error=>{
onProcessed(error)
});
}
function onProcessed(error, result) {
++processed;
if (error !== null) {
console.error(error);
}
if (processed === totalExecutions) {
console.log('all done');
}
}
How often does it reproduce? Is there a required condition?
Until node v20.2.0, it works as expected, i.e., primary process never closes the socket, from v20.3.0 onwards, it does not work as expected, primary process sometimes closes the socket. In some environments, if totalExecutions in above browser snippet is changed to 7, it reproduces the error consistently.
What is the expected behavior? Why is that the expected behavior?
As in node v20.2.0 (irrelevant of whether connection is close or keep-alive), primary process should never close the socket. In worker process, socket is closed (see the example worker.js above).
What do you see instead?
Primary process closes the socket and the client (browser) gets the following message:
Additional information
Basic Hardware Info:
memory 64KiB BIOS
memory 16GiB System Memory
memory 8GiB SODIMM DDR4 Synchronous 2400 MHz (0.4 ns)
memory 8GiB SODIMM DDR4 Synchronous 2400 MHz (0.4 ns)
memory 256KiB L1 cache
memory 1MiB L2 cache
memory 8MiB L3 cache
processor Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
disk 500GB NVMe disk