¿Cómo puede NodeJS ser "sin bloqueo"?

14

Estoy aprendiendo NodeJS y solo quería aclarar algo. En varios tutoriales y libros introductorios hasta el momento, describieron muy pronto la arquitectura "sin bloqueo" de Node, o mejor dicho, es posible (y se recomienda, todo el punto) codificar de manera no bloqueante.

Entonces, por ejemplo, este ejemplo se dio en un libro que estoy leyendo sobre una forma asincrónica de obtener datos de una base de datos.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

Lo que sucede (según tengo entendido) es que Node realiza la llamada a la base de datos, luego continúa procesando lo que pueda ser el próximo en la pila de llamadas. Cuando se completa la solicitud de la base de datos, la variable de datos en la función de devolución de llamada anónima se completará y esa función se agregará a la pila de llamadas (y posteriormente se ejecutará cuando Node llegue a ella).

Mi pregunta es, ¿qué es exactamente el procesamiento de la solicitud de la base de datos? ¿Seguramente Nodo tiene que bloquear mientras hace eso? ¿Qué se ocupa de la solicitud de la base de datos? O si Node está esperando una solicitud GET HTTP asíncrona a un recurso externo, ¿qué se está ocupando de esa solicitud que le permite a Node continuar procesando la pila de llamadas y "sin bloqueo"?

Anónimo
fuente

Respuestas:

17

Cuando Node.js se describe como "sin bloqueo", eso significa específicamente que su IO no es bloqueante. Node usa libuv para manejar su IO de una manera independiente de la plataforma. En Windows, usa puertos de finalización de E / S, en Unix, usa epoll / kqueue / select / etc. Por lo tanto, realiza una solicitud de E / S sin bloqueo (que puede tener una supervisión de subprocesos en segundo plano, pero esto nunca está expuesto a JavaScript) y, como resultado, la coloca en la cola del evento que llama a la devolución de llamada de JavaScript en el principal (lea: solo) hilo de JavaScript.

Para las bases de datos, depende de cómo se escriba la biblioteca. Si usa HTTP para comunicarse (como lo hacen algunas bases de datos NoSQL), entonces podría escribirse fácilmente en JavaScript puro usando la httpbiblioteca de nodos estándar . Si lo hace de otra manera, bueno, eso depende de la biblioteca. Podría escribirse en C / C ++ y usar subprocesos de fondo siempre que esa abstracción nunca esté expuesta al JavaScript.

En cuanto a su pregunta sobre qué es "procesar" la solicitud de la base de datos, idealmente todo lo que debe hacerse es enviar un mensaje simple a una biblioteca (por ejemplo, una declaración SQL o alguna otra consulta o una solicitud de conexión), y en ese momento su JavaScript sigue traqueteando. Cuando la biblioteca está lista para enviar un mensaje de regreso, envía un mensaje de regreso a la cola de eventos del nodo que ejecuta la devolución de llamada, permitiendo que se ejecute ese fragmento de código.

ckknight
fuente
Existe el netpaquete cuando http no está disponible.
Florian Margaine
Detalle que podría ayudar. Node aprovecha el motor V8 JS. Una de las mejores características de V8 es la facilidad de vincular procesos C / C ++ a llamadas JS. Las funciones de JavaScript están bloqueando, pero todo lo que hace una función es llamar a algo bajo el capó que no se bloquea. Luego, otra función JS responde cuando se completa ese proceso. Las funciones de JS se bloquean entre sí, lo que significa que nunca tendrá dos cosas tratando de hacer algo como programar una escritura en la misma ubicación de archivo al mismo tiempo, que es donde supongo que se deben administrar varios subprocesos. Siempre está claro qué solicitud vino primero con el fin de hacer cola.
Erik Reppen