Skip to content

Can I use Master, and Workers process communication when also using Sticky Session? #36

@Trysonic

Description

@Trysonic

I'm trying to use sticky-session for socket.io as a load balancer.

I use this example from the main page:

    var express = require('express'),
        cluster = require('cluster'),
        net = require('net'),
        sio = require('socket.io'),
        sio_redis = require('socket.io-redis'),
        farmhash = require('farmhash');
    
    var port = 3000,
        num_processes = require('os').cpus().length;
    
    if (cluster.isMaster) {
    	// This stores our workers. We need to keep them to be able to reference
    	// them based on source IP address. It's also useful for auto-restart,
    	// for example.
    	var workers = [];
    
    	// Helper function for spawning worker at index 'i'.
    	var spawn = function(i) {
    		workers[i] = cluster.fork();
    
    		// Optional: Restart worker on exit
    		workers[i].on('exit', function(code, signal) {
    			console.log('respawning worker', i);
    			spawn(i);
    		});
        };
    
        // Spawn workers.
    	for (var i = 0; i < num_processes; i++) {
    		spawn(i);
    	}
    
    	// Helper function for getting a worker index based on IP address.
    	// This is a hot path so it should be really fast. The way it works
    	// is by converting the IP address to a number by removing non numeric
      // characters, then compressing it to the number of slots we have.
    	//
    	// Compared against "real" hashing (from the sticky-session code) and
    	// "real" IP number conversion, this function is on par in terms of
    	// worker index distribution only much faster.
    	var worker_index = function(ip, len) {
    		return farmhash.fingerprint32(ip) % len; // Farmhash is the fastest and works with IPv6, too
    	};
    
    	// Create the outside facing server listening on our port.
    	var server = net.createServer({ pauseOnConnect: true }, function(connection) {
    		// We received a connection and need to pass it to the appropriate
    		// worker. Get the worker for this connection's source IP and pass
    		// it the connection.
    		var worker = workers[worker_index(connection.remoteAddress, num_processes)];
    		worker.send('sticky-session:connection', connection);
    	}).listen(port);
    } else {
        // Note we don't use a port here because the master listens on it for us.
    	var app = new express();
    
    	// Here you might use middleware, attach routes, etc.
    
    	// Don't expose our internal server to the outside.
    	var server = app.listen(0, 'localhost'),
    	    io = sio(server);
    
    	// Tell Socket.IO to use the redis adapter. By default, the redis
    	// server is assumed to be on localhost:6379. You don't have to
    	// specify them explicitly unless you want to change them.
    	io.adapter(sio_redis({ host: 'localhost', port: 6379 }));
    
    	// Here you might use Socket.IO middleware for authorization etc.
    
    	// Listen to messages sent from the master. Ignore everything else.
    	process.on('message', function(message, connection) {
    		if (message !== 'sticky-session:connection') {
    			return;
    		}
    
    		// Emulate a connection event on the server by emitting the
    		// event with the connection the master sent us.
    		server.emit('connection', connection);
    
    		connection.resume();
    	});
    }

My problem are these lines:

	// Listen to messages sent from the master. Ignore everything else.
	process.on('message', function(message, connection) {
		if (message !== 'sticky-session:connection') {
			return;
		}

		// Emulate a connection event on the server by emitting the
		// event with the connection the master sent us.
		server.emit('connection', connection);

		connection.resume();
	});

For my app, I need to use "process.on / process.send" communication, as well as "worker[worker_id].send" when in my Master cluster.

Is it banned to do so with sticky session? Can it break the communication?

I want to use something like that:

	process.on('message', function(message, connection) {
		if (message !== 'sticky-session:connection')
		{
			if(message.action == "calculX")
			{
				//redirect to function in this worker
			}	
			if(message.action == "calculY")
			{
				//redirect to function in this worker
			}				
			
			return;
		}

		// Emulate a connection event on the server by emitting the
		// event with the connection the master sent us.
		server.emit('connection', connection);

		connection.resume();
	});

Is it allowed or will it break the "connection" system?

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions