When I run my node app.js application, the process has only 1 thread. However, the more time that runs, the more threads run for the process. The problem is that when I want to execute a certain type of code as follows:
var io = require('socket.io')(process.env.PORT);
It fails because the signal was sent from multiple threads, and therefore the code was not executed successfully.
A simple test if you do this:
var io = require('socket.io')(9001); var io = require('socket.io')(9002); var io = require('socket.io')(9003); var io = require('socket.io')(9004);
It works fine, but this code:
var cPort = 9001; setInterval(function() { var io = require('socket.io')(cPort); cPort++; }, 1000 * 60 * 2);
will not be executed, because after 2 minutes the node will have many threads, and all of them will try to execute the code - as a result, you will see error: address in use .
So, despite the execution of a multi-threaded process of the same file, how can I get node to execute this code only once?
11/06/2017 EDIT ----
To clarify the problem:
What do I mean in the question, I have no problems with resources, if I start all the servers at once (for example, 40 servers), they all start up successfully and work indefinitely. The problem occurs if I start only one server, and then run the code, which automatically runs when necessary. At this point, I always see an address in use error, it is obvious that the address is not used at the time of code execution. Currently, I have to manually start more servers on weekends, when on other days of the week more people use the service and fewer servers, so I wanted to create an automated system that starts and closes servers based on the population.
this is the server startup code:
var cp = require('child_process'), servers = [], per_server = config.per_server, check_servers = function(callback) { for(var i = 0; i < servers.length; i++) { callback(i, servers[i]); } }; this.add_server = function(port) { var server = { port: port, load: 0, process: cp.fork(__dirname + '/../server_instance.js', [], { env: { port: port } }) }; server.process.on('message', function(message) { server.load = message.load; }); servers.push(server); }; this.find_server = function() { var min = Infinity, port = false; check_servers(function(index, details) { if(details.load < min) { min = details.load; port = details.port; } }); return port; };
now, if I execute controller.add_server() 40 times in a row, it will start 40 servers correctly, but if I do this:
var start_port = 3185; setInterval(function() { var min = Infinity; check_servers(function(index, details) { if(details.load < min) { min = details.load; } }); if(min > config.per_server) { controller.add_server(start_port); start_port++; } }, 5000);
I get a random error when creating a second, third or fourth server that is already in use.
11/07/2017 EDIT ----
As I said, I tried the following libraries for scanning / searching for ports:
Only the first time I was able to start at least 2 servers, this is the code I used:
setInterval(function() { var min = Infinity; check_servers(function(index, details) { if(details.load < min) { min = details.load; } }); if(min > per_server) { _self.add_server(); } }, 5000); var portfinder = require('portfinder'); portfinder.basePort = 3185; this.add_server = function() { portfinder.getPortPromise() .then((port) => { console.log('port found', port); var server = { port: port, load: 0, process: cp.fork(__dirname + '/../server_instance.js', [], { env: { port: port } }) }; server.process.on('message', function(message) { server.load = message.load; }); servers.push(server); }) .catch((err) => { console.log('error happened'); }); };
After doing many tests, it looks like I can start 2 servers and then random them, crashing on the third or fourth attempt. Clearly, the problem is deeper than with port discovery, this library only tells me that I already know, I know which ports are open, and I double-check that before the script tries to start the server using the netstat -anp | grep PORT netstat -anp | grep PORT .
So, itโs clear that the problem is not in finding open ports, but in terms of the result, it looks like node is trying to start the server several times from one command.
track EDIT ----
adding server_instance.js code:
var io = require('socket.io')(process.env.port), connections_current = 0, connections_made = 0, connections_dropped = 0; io.on('connection', function(socket) { connections_current++; connections_made++;
11/08/2017 EDIT ----
I tested many solutions to solve the problem, and I observed this situation:
local test on mac osx where I can create a maximum of 3000 server connections. The error will never happen, node has 1 process and 6 threads for the router file. With 3,000 connections, I can create even 200 servers without any problems.
server test on linux debian, where I generate 2 million connections to the server. The error always occurs on the 3rd or 4th instance of the server when I connect all node people with 6 processes and 10 threads for every process for the router file.
This is clearly the source of the problem, the more capacity I have, the more node processes occur, and earlier it will overlap when trying to start a new server.