- BACKEND
- FEBRERO 2020
Mucho cuidado con la asincronía en NodeJS
Suscríbete a Insights
Déjanos tu email y te mantendremos al tanto de todas nuestras publicaciones. Solo recibirás una comunicación al mes aproximadamente. Tranquilo, no mandamos spam ;)
Si eres desarrollador (tanto de NodeJS como de otros lenguajes) seguro que te han contado las maravillas de la asincronía de NodeJS. La idea de asincronía es que se envía una petición, y mientras que se espera a recibirlo, se siguen haciendo otras operaciones. Y no vamos a decir que esto no sea genial, es más, ahí reside su magia, pero hoy vamos a ver algo de la sincronía en NodeJS con lo que tener un especial cuidado si no queremos crear graves problemas en el servidor.
Asincronía en NodeJS vs PHP
NodeJS (y en general JavaScript), no trabaja de la forma clásica como lo hace un script en Python o en PHP, si no que es asíncrono por defecto. En Python y PHP claro que se pueden plantear solicitudes asíncronas, pero por defecto son síncronos. Esta característica especial de NodeJS se debe al Event Loop.
Planteemos el siguiente flujo de ejemplo para nuestras pruebas:
- Hacemos una petición web para pedir datos de un producto en un sistema eCommerce.
- Enviamos los datos de usuario y el producto a un servicio, que los guardará y procesará para formar parte de un Bigdata.
- Posteriormente buscamos en la base de datos el producto, y lo devolvemos al usuario para que lo represente en el Frontend.
Un lenguaje síncrono manda el mensaje a la cola y queda bloqueado a la espera de que le devuelva el resultado. En cambio en NodeJS se envía el mensaje pero no se espera, continúa con la siguiente petición a la base de datos y envía los datos. En el caso en el que el servicio donde enviamos los datos esté caído, podemos obtener un error y deberíamos gestionar dicha anomalía.
Reventemos nuestro server NodeJS
Vamos a destruir con un ejemplo, que es lo que mola! Teniendo un servidor NodeJS + Express con dos endpoints, uno /normal que devuelve el mensaje normal y otro /loop que nos bloqueará todo el sistema.
const express = require('express');
const app = express();
const bigNumber = 100000000000000000;
app.listen(3000, function() {
console.log('listening on 3000')
})
app.get('/loop', function (req, res) {
console.log('Infinite loop that will break the server.');
for (i=0; i < bigNumber; i++)
{
}
res.send('Exit.');
})
app.get('/normal', function (req, res) {
console.log('Ordinary page.');
res.send('Normal');
})
Si observas el código verás que no es un bucle infinito pero sí muy grande. Si entramos de primeras en /normal, vemos que entra sin problemas. Podemos refrescar la página todas las veces que queramos, que el servidor va a seguir funcionando bien, sin problemas. Si por otro lado entramos en /loop, el servidor se volverá loco, y no mandará la petición. Pero además, si mientras está ahí esperando vamos a /normal, tampoco funciona, hemos bloqueado todo node.
Multihilo en PHP
Ahora veamos cómo actúa PHP en un Apache. Cada vez que vamos a un endpoint (que es un archivo .php en el servidor Apache) crea un nuevo hilo. Este hilo puede consumir más o menos RAM y CPU, pero no bloquea el sistema, salvo que abramos muchos loops. Por otro lado, Apache corta el hilo cuando emplea más de un determinado tiempo máximo, que por defecto está en 120 segundos.
Igual que con node podemos probar el server de la siguiente manera:
- localhost:3001/normal.php: para el proceso normal.
- localhost:3001/loop.php: para intentar reventar el server.
Si pruebas a entrar en /normal.php va a la perfección. Pero si entras en /loop.php, no responderá nada; es más, a los dos minutos debería mandar un error. Pero si le das de nuevo a /normal.php funcionará igualmente, salvo que le des muchas veces a /loop.php en cuyo caso Apache abrirá muchos hilos y consumirá toda tu RAM o CPU.
normal.php
<?php
echo "normal";
?>
loop.php
<?php
const bigNumber = 100000000000000000;
for ($i = 1; $i <= bigNumber; $i++) {
echo $i;
}
?>
bucle
Conclusión
NodeJS es una gran plataforma, y para nuestro gusto actualmente uno de los mejores lenguaje para Web. Por su asincronicidad, hace que por norma general sea fácil crear aplicaciones, mantenerlas, es potente, es rápido, vamos... todo maravillas. Pero por lo que hemos explicado, debemos tener especial cuidado con los bucles, no solo for o while, también foreach, filters, maps y funciones que las usen.
Pero cada herramienta ha de ser utilizada de forma adecuada, y la decisión está en el programador sobre si el utilizar NodeJS u otras opciones (como Python) para hacer Jobs.
Boream insights
Descubre tendencias y sigue el día a día de nuestros proyectos.
Ver todos los insights-
Backend Best practices
Potenciando Drupal con soluciones de Inteligencia Artificial (IA)
Casos de uso reales de cómo se puede aplicar la Inteligencia Artificial en la plataforma CMS Drupal, y por extensión a cualquier tipo de solución de Gestión de Contenidos actual.
-
UX-CX
Solid, UX y datos personales. ¿Una utopía o una realidad?
Solid es una tecnología basada en los estándares actuales de Internet que permite la organización de datos e identidades en las aplicaciones que desarrollemos. Hasta aquí poca cosa nueva. La revolución viene dada porque con esta tecnología es el propio usuario quien tiene el control de sus datos y quien da el permiso de uso a las compañías a través de un WebID.
-
Diseño UX-CX Research
Sesgos cognitivos y prejuicios en los procesos de diseño de interfaz: como combatirlos
Como diseñadores de interfaz y de experiencia de usuario debemos tomar decisiones rápidas que impactan de manera notable en el resultado final de nuestros productos digitales. Generalmente no somos conscientes de que estas decisiones pueden verse profundamente afectadas por una interpretación errónea de la realidad, sesgada por nuestra propia experiencia y alejada de una comprensión racional del entorno.
-
Backend Best practices
Desarrollo Drupal conexión con LDAP: control de acceso.
Tras el primer insight donde comentamos los pasos básicos de conexión de un desarrollo Drupal con un Sistema LDAP, en esta nueva entrega profundizamos en algunos aspectos más avanzados o particulares.