Procesos secundarios en Nodejs

Procesos secundarios en Node.js

Artículo básico sobre gestión de procesos secundarios en Nodejs. Una mirada al módulo de proceso secundario y las operaciones en segundo plano.


Concepto de proceso

Los procesos son la unidad básica del sistema operativo para la programación y asignación de recursos. Los procesos en una computadora son todos los programas que se ejecutan e interactúan con el procesador. Al iniciar un proceso, el sistema operativo asigna memoria y recursos para su ejecución. Al final de un proceso, el sistema libera estos recursos y el método de administración depende de la forma en que funciona cada sistema operativo en particular.

Algunas características a destacar de los procesos:

  • Cada proceso comienza inicialmente con un solo hilo principal.
  • Un proceso se compone de uno o más hilos.
  • Un proceso puede instanciar otros procesos llamados subprocesos.

Concepto de subproceso

Un subproceso es una opción para encapsular pasos lógicamente relacionados dentro de un proceso principal. El subproceso admite el proceso principal para realizar diferentes tareas programáticas en segundo plano.

Algunas características notables del subproceso:

  • Son instanciados por un proceso padre.
  • El subproceso como tal es un proceso, por lo que también se componen de 1 o más hilos y pueden crear más subprocesos.

Subproceso en Nodejs

Muchos de los lenguajes de programación actuales contienen en su núcleo múltiples mecanismos para generar e interactuar con subprocesos. Nodejs en particular contiene un módulo llamado child_process que nos ayuda con esta tarea.

Algunos ejemplos de subprocesos a instanciar:

  • Abre un navegador.
  • Haga ping a una dirección IP.
  • Abre el bloc de notas.
  • Ejecutar comandos por consola.
  • Entre otros.

Este es un ejemplo de un programa de Nodejs que muestra un nuevo subproceso de Google Chrome en el sistema operativo. Abriendo una pestaña y consultando la dirección de YouTube:

const { exec } = require('child_process');url = "https://www.youtube.com/";
cmdCommand = `start chrome /new-tab ${url}`;
exec(cmdCommand);

Este es el resultado:

Procesos secundarios

Proceso hijo del módulo

Como se mencionó anteriormente, este módulo nos brinda la capacidad de generar nuevos procesos. Este módulo está diseñado para trabajar con tareas a largo plazo e interactuar con el sistema operativo.

El módulo child_process contiene los siguientes métodos principales que nos ayudarán a crear, manipular y ejecutar procesos: exec, spawn y fork.

Algunas características a destacar de estos métodos en Nodejs:

  • Inherit from EventEmitter: por lo tanto, te permiten escuchar eventos como error , close y message.
  • Estándar Stdio: Adicionalmente se pueden utilizar los 3 estándares stdio como stdin , stdout y stderr.

Exec

El método exec genera un nuevo proceso de shell y continúa con la ejecución de comandos en ese shell.

En el siguiente ejemplo, instanciamos un proceso de shell y ejecutamos el comando ping con la dirección de google.com.

const { exec } = require('child_process');exec('ping google.com', (error, stdout, stderr) => {
  
  if (error) {
    console.error(`error: ${error.message}`);
    return;
  }if (stderr) {
    console.error(`stderr: ${stderr}`);
    return;
  }console.log(`stdout:\n${stdout}`);
});

Esto da como resultado lo siguiente:

Pinging google.com [142.251.0.101] with 32 bytes of data:
Reply from 142.251.0.101: bytes=32 time=7ms TTL=107
Reply from 142.251.0.101: bytes=32 time=11ms TTL=107
Reply from 142.251.0.101: bytes=32 time=11ms TTL=107
Reply from 142.251.0.101: bytes=32 time=8ms TTL=107Ping statistics for 142.251.0.101: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds: Minimum = 7ms, Maximum = 11ms, Average = 9ms

Tenga en cuenta que el resultado del comando se mantiene en un búfer en la memoria, que puede aceptar a través de una función de devolución de llamada que se pasa a exec como se muestra en el ejemplo.

spawn

El método de generación crea un nuevo proceso ejecutando un comando con manipulación de flujo. Este método está diseñado para trabajar con cargas de trabajo intensivas.

En el siguiente ejemplo, ejecutamos el comando find para buscar archivos en el directorio actual y escuchar eventos en stdout, stderr, error y close. Todo trabajado con corrientes.

const { spawn } = require('child_process');const subProcess = spawn("find", ["."]);subProcess.stdout.on('data', (data) => {
  console.log(`stdout:\n${data}`);
});subProcess.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});subProcess.on('error', (error) => {
  console.error(`error: ${error.message}`);
});subProcess.on('close', (code) => {
  console.log(`child process salida ${code}`);
});

Esto da como resultado lo siguiente (mis archivos en ese momento):

stdout:
.
./array_2D.js
child process salida 0

A diferencia de exec, que funciona con devoluciones de llamadas, spawn funciona con flujos. Esto nos permite ejecutar procesos por mucho más tiempo y de una manera mucho más asincrónica.

fork

El método de bifurcación genera un nuevo proceso con comunicación entre padre e hijo (proceso y subproceso). Este método está destinado a trabajar con bifurcaciones y convergencia.

En el siguiente ejemplo, crearemos una instancia de un proceso secundario que enviará información al proceso principal en 5 segundos (simulación asíncrona).

proceso hijo (child.js)

setTimeout(() => {
process.send("Hello father, I send this information")
}, 5000);

proceso principal (father.js)

const { fork } = require('child_process');const subProcess = fork("./child.js");subProcess.on('message', (message) => {
  console.log(`I get this from the son : ${message}`);
});

Esto da como resultado lo siguiente:

I get this from the son : Hello father, I send this information

Los mensajes entre un proceso padre e hijo creados por fork son accesibles a través del objeto global Node llamado “process“. Además, con fork podemos controlar cuándo un proceso hijo inicia una actividad o también devolver datos de un proceso hijo a un proceso padre y viceversa.

Recursos Procesos secundarios de Nodejs

Finalizando

Saber manejar procesos secundarios en Nodejs es de gran utilidad cuando se trata de operaciones con uso intensivo de CPU, se recomienda utilizar nuevos subprocesos o generar nuevos hilos dependiendo de la tarea a realizar.


Gracias por llegar hasta aquí, si encuentras esto útil no olvides aplaudir 👍🏼suscribirse para recibir más contenido.

Si necesita ayuda adicional, por favor contácteme.


Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre AWS y Laravel:

Recent Post