Curso de




Día 6: Procesos

Vuestro anfitrión


(según mi hija de 5 años)

Ingeniero senior en MediaSmart Mobile
Co-organizador de Node.js Madrid
@pinchito

Guión


  • Temporizadores
  • Sesión práctica: intervalos falsos
  • Procesos
  • Sesión práctica: controla tus procesos
  • Clusters
  • Sesión práctica: crea tu propio cluster

Temporizadores


Tempus fugit

Temporizadores JavaScript (1/2)

var timeout = setTimeout(operation, timeMs); 

Lanza una operación tras un tiempo

clearTimeout(timeout); 

Cancela la operación


var interval = setInterval(operation, timeMs); 

Lanza una operación cada cierto tiempo

¡no es 100% preciso!

clearInterval(interval); 

Cancela la repetición

Temporizadores JavaScript (2/2)


var immediate = setImmediate(operation); 

Lanza una operación inmediatamente

Tras los eventos de entrada/salida

(Sólo IE y Node.js)

clearImmediate(immediate); 

Cancela la operación


Fuente: MDN Timers

Tiempo JavaScript


Baja precisión: Date.now()

Fecha con milisegundos


Alta precisión: process.hrtime()

Segundos y nanosegundos 


Fuente: MDN, process

Sesión Práctica 1: intervalos falsos


Crear un intervalo


Comprobar que no se respeta (!)


Controlar la memoria usada

Especificación técnica


Ejecutar un intervalo cada milisegundo

Actualizar un contador cada vez


Tras un segundo, detener la ejecución

Mostrar el número de ejecuciones reales

y el tiempo real

y las iteraciones por segundo reales

Instalar performance


$ npm install performance
$ npm start
Verificar el rendimiento de la máquina
y comparar con el resto

Good job!

Procesos


Controla la máquina

Node.js Process


process.argv 

Contiene las opciones de comando

process.env 

Contiene las variables de entorno

process.exit() 

Sale del programa

process.memoryUsage() 

Uso de memoria


Fuente: process

Señales


Se capturan con process:

process.on('SIGINT', function() {
  console.log('Mi sentido arácnido detecta un SIGINT');
});


Señales típicas:

  • SIGTERM: termina manualmente

  • SIGINT: Control-C

  • SIGHUP: desvincula la consola

  • SIGKILL: -9, no capturable

Sesión práctica 2


Crear 10000 objetos


Meterlos en un mapa


Comprobar la memoria usada

antes y después

Ejercicios


Capturar las excepciones genéricas


Lanzar una excepción en el código

Verificar que se caza


Cazar Control-C y no salir

Good job!


Clusters


Aprovecha esos cores

El mundo antes de los cores


Muchos transistores, pocos cores

Multicore is eating the world



Fuente: EE Times

Así que, ¿qué piensas hacer con todos esos cores?

Módulo Cluster


API "experimental" para controlar el multiproceso


Un master, varios workers


Los sockets se comparten


Fuente: GodTIC

Modelo Unix: fork()


var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
} 
Fuente: cluster

Mensajes


Envío: 

process.send(message); 

Recepción:

Object.keys(cluster.workers).forEach(function(id) {
    cluster.workers[id].on('message', messageHandler);
});

De los workers a master

También disponible al revés


Fuente: child_process


Sesión práctica 2: crea tu cluster


Arranca el servidor de sockets en cluster


Atrapa todas las excepciones sin cazar


Recuerda matar los workers al salir!

Servidor de sockets


var net = require('net');
var port = 1702;
var server = net.createServer(function(connection) {
    console.log('Connection to %s open', port);
    connection.write('Hello?\r\n');
    connection.on('data', function(data) {
        if (String(data).trim() != 'hello) {
            connection.write('ERROR\r\n');
        } else {
            connection.end('world\r\n');
            console.log('Connection to %s closed', port);
        }
    });
});
server.listen(port);

Copia, pega y colorea

Ejercicios


Cada vez que se conecte alguien
aumenta un contador global

Al terminar master con Control-C, muestra
el total de conexiones


Mata un worker cada minuto
y crea uno nuevo

Good job!



Thanks!