node icon indicating copy to clipboard operation
node copied to clipboard

[Cluster] Primary process closes socket sporadically in linux

Open pmadhur opened this issue 1 year ago • 2 comments

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: Screenshot 2024-01-27 171724

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

pmadhur avatar Jan 27 '24 16:01 pmadhur

In v20.3.0, whenever the primary process closes the socket, the function socketOnEnd gets called. In v20.2.0, socketOnEnd is never called. Screenshot 2024-01-28 094424

pmadhur avatar Jan 28 '24 08:01 pmadhur

The issue is reproducible without any third party environments/modules on Ubuntu 22.04.3.

pmadhur avatar Feb 03 '24 08:02 pmadhur