Brian
Brian

Reputation: 3023

Multi-threaded socket.io in single process in node.js application

I've been digging around trying to see if anyone else has run into this, but I sort of expected not and that's what I found.

The problem I'm facing right now is related to the architecture of the application I'm building; a game server in node.js. As of right now, the server starts up with a single "manager" process which has control over all the child processes. Each "zone" or "area" of the game is spun up using cluster.fork() using a separate process so that each "zone" can have its own thread on the server to optimize the ability for the server to run many of these "zones" at once.

The dilemma I'm facing right now is this. Since each "zone" is running in a single thread, and that thread is already going to be running complex 3D math X times per second to keep the "zone" in sync, I don't want to open Socket.io (the communication library used for talking with the game client) in that same thread. I guess where I'm hung up is on the performance of using the cluster.on('message') handler in the master process and piping messages from Socket.io into the master process using process.send({...}).

I'm trying to see if anyone else has experience with this or knows on a fundamental level how that whole cluster module works and essentially this:

Is it faster to call:

var io = require('socket.io').listen( 1337 );
io.sockets.on('connection',...); //map all the functionality here in the "zone" thread

Or to do something more like this:

var cluster = require('cluster');
var io = [];
//arbitrary number for the thread count, not important for theory testing
for( var i = 0; i < 4; ++i) {
    var process = cluster.fork({...});
    process.on('message',myRelayFunction);
    io.push( process );
}

Assuming of course that the cluster.fork() call was piping into a script that did nothing but open a socket.io connection and relay the messages from the various clients into the "zone" process.

I've tried running performance tests on this, but I'm finding it very hard to tell if this is faster or not since I'm having difficulty saturating the machine with connections to get the output to test with.

I want to make sure this is scalable so that under a heavier load, the application can make the best use of multiple CPU cores on a server. So that of course says I should multi-thread the socket.io listeners into several threads, but my concern is that since they're all technically piping back into a single threaded process, wouldn't that cost me any possible performance increase of multi-threading them? I'm kind of coming up empty in the testing/benchmarking department here and I don't know the theory behind how all this works well enough to say what's the best fundamental approach here... so I would very much appreciate any feedback/input anyone has on this ;)

Upvotes: 3

Views: 3423

Answers (1)

Brian
Brian

Reputation: 3023

I was able to do some more testing and it seems that having the socket.io listeners in a separate thread is still very beneficial to performance even if they have to pipe data in/out of the single "zone" (manager) process. This way the server can use a separate CPU to handle the IO processing than the zone processing.

So the answer here is that yes, it's still beneficial to multithread your listeners/sockets into separate threads, even if all of those threads are communicating with a single thread for something. That of course leads into the other issue I was experiencing, which was how to best optimize communication between multiple child processes in node.js Since that's the next logical step/hurdle in this process, I'm linking to that question below in case anyone else ends up stumbling their way through this problem later.

Inter-child-process communication options in node.js cluster

Upvotes: 4

Related Questions