No lo intentes en casa: E/S síncrona en Node.js

Rate this content
Bookmark

Node.js es famosamente un tiempo de ejecución de JavaScript que fomenta el uso de operaciones asíncronas siempre que sea posible, pero ¿qué sucede cuando realmente, realmente necesitas hacer E/S síncrona? Anna ofrece una visión general de las muchas y sorprendentes formas de lograr esto, y lo que podemos aprender sobre cómo funciona el lenguaje y las internas de Node.js a partir de ellas.

32 min
24 Jun, 2021

Video Summary and Transcription

Esta charla explora la E/S síncrona en Node.js y las ventajas de la E/S asíncrona. Se discuten las excepciones a la E/S síncrona y los enfoques para lograr la E/S síncrona en Node.js, incluido el uso de WASI y complementos nativos. La charla también aborda la mezcla de trabajadores con atómicos para la E/S síncrona y la incorporación de Node.js para crear un trabajador síncrono. Además, se menciona la migración a TypeScript, las optimizaciones en Node.js y las experiencias y consejos sobre cómo contribuir a Node.js.

Available in English

1. Introducción a la IO síncrona en Node.js

Short description:

Hola a todos. Soy Anna y hablaré sobre la IO síncrona en Node.js. Tengo experiencia en el Comité de Dirección Técnica de Node.js y ahora formo parte del equipo de herramientas de desarrollo de MongoDB.

Hola a todos. Soy Anna y voy a hablar un poco sobre la IO síncrona en Node.js. Antes de comenzar, ¿quién soy yo? Soy Anna, mis pronombres son ella, ella. Anteriormente formé parte del Comité de Dirección Técnica de Node.js, así que me pagaban a tiempo completo para trabajar en el núcleo de Node.js. En septiembre, me uní al equipo de MongoDB, al equipo de herramientas de desarrollo. Y mi nombre de usuario, si tienen alguna pregunta o quieren contactarme de alguna otra manera, es addalex en Twitter y GitHub, al menos. Y también soy la mamá de estos dos pequeñitos adorables.

2. Synchronous vs Asynchronous IO in Node.js

Short description:

Las formas síncrona y asíncrona de cargar archivos en Node.js dan el mismo resultado, pero la forma síncrona tiene problemas de rendimiento. Inicialmente, esperaba que la versión síncrona fuera ligeramente más rápida para una sola llamada, pero descubrí un error en la versión asíncrona que afectaba el rendimiento. Sin embargo, ahora la versión asíncrona es más rápida. La ventaja de la IO asíncrona es que pueden ocurrir múltiples cosas al mismo tiempo, lo que permite operaciones concurrentes.

Pero, sí, tratemos de recordar, como, el subtítulo de esta charla es no intentes esto en casa. Y, como, ¿por qué no queremos hacer IO síncrona en Node.js? Estoy bastante seguro de que has escuchado que no deberías, pero ¿por qué? Así que aquí tienes lado a lado. En el lado izquierdo tienes la forma clásica síncrona de cargar, de hacer IO, de cargar un archivo desde el disco. En el lado derecho, tienes una forma asíncrona, y en este caso, también podrías decir que es más moderna porque es asíncrona. Al final, estas dos dan el mismo resultado. Y, bueno, ¿por qué no queremos el lado izquierdo? ¿Por qué no queremos que la gente haga lo que está en el lado izquierdo? La razón es el rendimiento. Y antes de entrar en detalles sobre eso, así que, como, si haces una prueba de referencia de fs.refi, intenté hacer eso para esta charla. Lo que esperaría que suceda es que la versión síncrona sea ligeramente más rápida que la versión asíncrona si solo haces una sola llamada porque la versión síncrona solo tiene que ir y leer el archivo y devolver los resultados. Y la versión asíncrona, en realidad tiene que programar eso y luego esperar a que los resultados regresen. Así que, esperaría que la versión asíncrona sea un poco más rápida que la versión síncrona. En primer lugar, al principio eso era cierto, pero eso fue, como, mucho más rápido que en realidad descubrí un error en fs.promises.refi que afectaba el rendimiento. Y después de solucionar eso, no sé, la versión asíncrona es más rápida por alguna razón. Si quieres, siéntete libre de investigar esto y decirme qué está pasando. Pero, sí, en general, eso es lo que esperaría. Pero de todos modos, la gran ventaja es que pueden ocurrir múltiples cosas al mismo tiempo. Esa es la idea general de Node.js. Puedes hacer algo, hacer algo más y esperar a que estas dos cosas sucedan antes de continuar. Y otras cosas también pueden suceder mientras esas operaciones están en curso. Con la forma síncrona, todo sucede uno tras otro. Y mientras tu proceso hace esta carga de archivos, no puede suceder nada más. No JavaScript, no otra IO, nada.

3. Excepciones a la IO síncrona en Node.js

Short description:

Existen excepciones a la IO síncrona en Node.js. La carga de código requerido y la importación de ESM realizan IO síncrona en el sistema de archivos, pero no es necesario. Se recomienda escribir código asíncrono incluso si no es estrictamente necesario. El tercer caso es cuando se necesita código síncrono, como cuando una API o interfaz de usuario lo requiere. Actualmente estoy trabajando en reescribir la utilidad de línea de comandos de Mongo como una aplicación de Node.js llamada Mongosh. Las aplicaciones JavaScript son más fáciles de mantener y podemos incrustar Mongosh en aplicaciones Electron y páginas web.

Pero sí, existen excepciones a cuando está bien hacer esto. No deberías. Pero en algunos casos. Entonces, la carga de código requerido y, hasta donde sé, también la importación de ESM, realizan IO síncrona en el sistema de archivos. Para ESM, eso no es algo técnicamente necesario. Y espero que podamos prescindir de eso en algún momento. Pero sí, porque la carga de ESM es asíncrona de todos modos y no necesariamente notarías si el sistema de archivos estuviera ocurriendo de forma asíncrona.

El segundo caso es cuando sabes absolutamente que lo que estás haciendo es lo correcto. Por ejemplo, estás escribiendo una aplicación de línea de comandos donde hay un conjunto muy limitado de cosas que suceden al mismo tiempo y sabes que no está ocurriendo nada más al mismo tiempo. Aún así, te animaría a escribir código asíncrono. Simplemente porque debes seguir esa mejor práctica, incluso si no es estrictamente necesario. Y el tercer caso es cuando necesitas código síncrono por alguna razón. Y eso puede ser porque alguna API o alguna interfaz de usuario expone tu código como síncrono y no tienes otra opción. Y voy a hablar sobre ese último caso aquí. ¿Qué hago actualmente en mi trabajo estos días?

Si alguna vez has trabajado con MongoDB, esto puede parecer un poco familiar. Existe una utilidad de línea de comandos de Mongo donde puedes pasar algo que se parece a una URL y decir, `conéctate a este servidor. Conéctate a esta base de datos`. Y luego obtienes una consola donde puedes ejecutar comandos como en este caso, db.test.find. No importa realmente para el ejemplo que esto sea MongoDB. Esto bien podría ser el cliente de MySQL y el comando podría ser select asterisco from test, básicamente lo mismo.

Entonces, el proyecto en el que estoy trabajando actualmente es en realidad reescribir esto, se llama Mongosh, dependiendo de cómo te guste pronunciarlo. Hace prácticamente lo mismo. Pasas algo similar a una URL y puedes obtener una consola y ejecutar el mismo tipo de comando allí. ¿Por qué estamos haciendo esto? Entonces, Mongo, la antigua consola es básicamente a lo que me he acostumbrado a llamarla. Es una aplicación C++ basada en Spider Monkey, por lo que es una aplicación C++ que utiliza el motor JavaScript de Firefox para ejecutar JavaScript desde la consola. Entonces, lo que estamos escribiendo, esta cosa llamada Mongosh, lo siento por eso, es una aplicación de Node.js. En primer lugar, las aplicaciones JavaScript son un poco más fáciles de mantener. Es simplemente un lenguaje de más alto nivel que C++, por mucho que me guste C++. Node.js ya tiene una gran representación en la que podemos construir, pero no tenemos que escribir todo esto de nuevo. E incluso podemos incrustarlo en aplicaciones Electron y tal vez en páginas web en algún momento.

4. Enfoques para la IO síncrona en Node.js

Short description:

Estamos construyendo sobre el controlador de Node.js y necesitamos hacer que el método haga algo de forma síncrona. La forma fácil es usar métodos síncronos, pero no cubren la IO de red. Creo que la existencia de operaciones de archivo síncronas es un defecto de diseño. Para lograr la IO síncrona en Node, puedes escribir código en C, Rust o C++ y compilarlo a Wasm.

En realidad, estamos haciendo eso primero. Hay una interfaz gráfica de usuario para MongoDB, que se llama Compass, que también es mantenida por nuestro equipo, y la incrustamos en una aplicación de Electron como un componente de React, lo cual es bastante genial. Pero sí, esta antigua consola, la forma en que funciona es que escribes algún comando como db.test.find, y realiza la IO de forma síncrona, porque no hay un bucle de eventos, nada, no hay Node.js involucrado. No hay razón para hacer algo asíncrono. Pero estamos construyendo sobre el controlador de Node.js. El controlador solo realiza IO de red. No tienes IO de red síncrona en Node. Simplemente no está ahí. Y eso fue complicado porque las personas no deberían tener que saber sobre async/await para poder usar nuestra consola. Las personas han escrito scripts para la antigua consola que idealmente queremos que sigan funcionando tanto como sea posible. Entonces, la pregunta es, ¿cómo hacemos que este método haga algo de forma síncrona? Eso es lo que me inspiró a dar esta charla. ¿Cuáles son los diferentes enfoques que podríamos tomar aquí?

Primero que nada, está la forma fácil de hacer IO síncrona en Node, que son los métodos síncronos. Simplemente están allí. Están en la API. Tienes FS que hace referencia a operaciones de archivo síncronas. Obviamente, no resuelve nuestro caso de uso aquí. Porque no cubre la IO de red. Y eso es lo que nos preocupa principalmente aquí. Así que eso es algo que no es viable para nosotros. Y también, si me preguntas, y esto es solo mi opinión personal, el hecho de que esto sea posible, que estas operaciones como readFileSync y operaciones similares estén allí, no hay una buena razón por la cual FileSystem.io en libuv en la biblioteca subyacente que soporta a Node esté implementado de la forma en que está. No hay una buena razón por la cual no debería funcionar de la misma manera que el acceso a la red o a los flujos de E/S estándar o cualquier otra cosa. Creo que eso es un defecto de diseño y no deberíamos poder tener estas cosas en primer lugar. Obviamente, no van a desaparecer porque millones de personas las están usando. Pero sí.

Entonces, luego... y esto es algo en lo que probablemente no pensarías al intentar hacer IO síncrona en Node... Lo que puedes hacer es escribir código en C, Rust o C++ y compilarlo a Wasm. Básicamente, cualquier cosa que sea compatible con Clang funcionaría aquí.

5. Usando WASI para IO síncrona en Node.js

Short description:

Puedes usar WASI, la Interfaz del Sistema de Web Assembly, soportada por Node.js, para ejecutar código de forma síncrona. Sin embargo, aún es experimental y no es muy útil para escribir JavaScript debido a la necesidad de serializar datos y usar búferes de arrays. Sí soporta la IO de red web.

Y luego puedes usar WASI, que es la Interfaz del Sistema de Web Assembly, que es soportada por Node.js, y usar eso para ejecutar ese código. Y cómo se ve eso en la práctica, entonces, en el lado izquierdo hay un archivo C. No importa realmente lo que hace, pero hay muchas llamadas que comienzan con F, lo que significa file.io. En el lado derecho, tienes el correspondiente JavaScript. Puedes crear estos objetos WASI. En Node.js, son experimentales, y necesitas pasar una bandera para que funcionen, pero están ahí y son soportados. Y usando estos pasos, puedes ejecutar este código en el lado izquierdo, y funcionará completamente de forma síncrona. Creo que esto es algo muy genial de tener, pero también es muy experimental, y actualmente no es muy útil para escribir JavaScript porque si quieres usar esto desde JavaScript, tendrías que actuar como una aplicación WebAssembly, lo que significa serializar todo lo que quieres pasar a una llamada en un búfer de arrays y enrutándolo de vuelta después. Y simplemente no es ergonómico en absoluto. Esto no es algo que queramos hacer. Pero hasta donde sé,

6. Fuerza bruta externa para IO síncrona en Node.js

Short description:

Podrías escribir un complemento nativo que cargues desde Node.js para realizar IO. Sin embargo, reimplementar toda la pila de red de Node.js solo para IO síncrona sería demasiado trabajo y no sería compatible con libuview.

esto admitiría IO de red web. Luego está la fuerza bruta externa, muy sencilla Node UA, que es escribir un complemento en C++ o Rust y no requiere mucho más que esto. Esto también sería un ejemplo funcional, excepto que obviamente falta el código de inicio. Pero podrías hacer esto. Podrías escribir un complemento nativo que cargues desde Node.js y que realice el IO por ti. Esto también es algo que no queremos reimplementar toda la pila de red de Node.js solo para tener IO síncrona en esto. Eso sería demasiado trabajo. No es algo que libuview admita, por lo que tendríamos que encontrar formas ingeniosas de hacerlo de otras maneras. Requeriría reescribir mucho código. No estamos haciendo eso.

7. Mezclando Workers con Atomics

Short description:

Y ahora, lleguemos a la parte emocionante: mezclar workers con atomics. Creamos un canal de mensajes y un búfer de matriz compartida. El hilo principal inicia un worker y espera en el búfer de matriz compartida. El worker recibe datos del hilo principal y ejecuta una función asíncrona utilizando NodeFetch para cargar solicitudes HTTP. Después de obtener la respuesta, la envía de vuelta al hilo principal utilizando atomic cert notify.

Y ahora, lleguemos a las formas que personalmente me emocionan más. Esto es probablemente mi favorito, porque en este punto está casi listo para producción y tal vez realmente podamos usarlo en el futuro.

¿Qué hacemos? Mezclamos workers con atomics y la razón por la que esto es el símbolo nuclear y no el emoji de átomo es que todos habrían pensado en React.

¿Cómo funciona esto? Veamos un ejemplo. Nuevamente, este es código que se puede ejecutar. El lado izquierdo, el lado del hilo principal, no tiene algunas importaciones. Pero básicamente funciona. Lo que hace el hilo principal, cuando se inicia, es crear un canal de mensajes y un búfer de matriz compartida. Y necesita un búfer de matriz compartida. Llegaremos a eso en un momento. Y luego inicia un worker al que le pasa un lado del canal de comunicación y ese búfer compartido de matriz. Y luego, espera en ese búfer de matriz compartida utilizando atomics.wait. Y en el worker eso sucede cuando se inicia. Bueno, obtiene los data que le envió el hilo principal. Y ejecuta una función asíncrona. Y eso es algo que ya te resulta muy familiar. Probablemente la mayoría de ustedes haya visto NodeFetch en algún momento. Es una API muy buena para cargar solicitudes HTTP. Y también es muy buena para estos ejemplos porque es muy sencillo hacer IO con ella. Aquí son solo tres líneas de código. Entonces, lo que sucede es que lo cargamos. Usamos una forma de buscarlo. Una forma de esperar a que se devuelva todo el cuerpo de la respuesta a nosotros. Obviamente, esto no incluye el manejo de errores. Pero ya sabes, no se hace eso en diapositivas como estas donde el espacio es limitado. Y luego, después de obtener esa respuesta, la enviamos de vuelta al hilo principal y usamos atomic cert notify. Es memoria compartida entre el hilo principal y el hilo del worker. Esto en realidad despierta esa llamada de espera que ocurrió en el hilo principal, que estaba bloqueada. Entonces, nada más progresó en el hilo principal. Todavía estaba esperando en esa línea a que alguien llamara a atomic cert notify en otro hilo.

8. Using Workers for Synchronous IO in Node.js

Short description:

Y luego, en el hilo principal, revisamos lo que obtuvimos, usamos el mensaje recibido de la API de terceros y mostramos la respuesta. Esta idea permite operaciones síncronas con algunas ventajas. El hilo principal se bloquea, crea un hilo de worker y espera la respuesta antes de avanzar. Node.js ofrece la API completa y paquetes NPM en el worker, pero hay desventajas. Atomics.wait no está permitido en los hilos principales de los navegadores y no es fácil manipular objetos dentro del worker. Sin embargo, está listo para producción y se puede utilizar en hilos de worker.

Y luego, en el hilo principal, revisamos lo que obtuvimos, usamos el mensaje recibido de la API de terceros, que es específico de Node.Jet. Puedes emularlo en la web, pero es un poco más conveniente de esta manera. Y luego mostramos la respuesta.

Esta idea general, creo que es bastante genial. Te permite hacer cosas de forma síncrona si realmente lo necesitas. Y tiene algunas ventajas. Entonces, nuevamente, así es como se ve esquemáticamente. El hilo principal se bloquea y no avanza. No vuelve a su propio bucle de eventos. Simplemente crea un hilo de worker, permite que ese bucle se ejecute y luego espera a que esa respuesta regrese antes de avanzar de alguna manera. Y las grandes ventajas de Node.js son que puedes usar la API completa de Node.js y los paquetes NPM en el worker. Las pequeñas desventajas son que Atomics.wait no está permitido en los hilos principales de los navegadores. Porque si lo estuviera, se vería. Atomics.wait es una llamada de bloqueo que no permite que nada progrese en el hilo principal. Entonces, bloquearía el renderizado, por ejemplo, indefinidamente, lo cual no es algo que debería permitir una página web. Y aún no nos da completamente lo que necesitamos, porque no permite manipular objetos dentro del worker. Entonces, si piensas en el ejemplo de fetch, si hubiéramos querido, por ejemplo, agregar un event listener al objeto de respuesta que vimos allí, no podríamos haberlo hecho fácilmente, porque no hay forma de acceder a estos objetos dentro del worker. Entonces, tendría que haber algún tipo de protocolo RPC que se encargue de eso. Y sí. Generalmente no es muy ergonómico de esa manera. Pero es muy genial. Muy listo para producción. No hubo nada experimental en lo que mostré. Y podrías usar esto, por ejemplo, dentro de un hilo de worker. Entonces, Atomic funciona dentro de los hilos de worker dentro del navegador.

9. Embedding Node.js and Synchronous Worker

Short description:

Fui a mi laboratorio de científico malvado y pensé en una solución para la E/S síncrona en Node.js. La idea es incrustar Node.js en sí mismo, iniciando una nueva instancia en el mismo hilo. Esto elimina la necesidad de hilos separados y reduce la complejidad. Se me ocurrió un proyecto llamado trabajador síncrono, que logra el resultado deseado.

Podrías hacer cosas como esta. Pero, sí. De todos modos. Ninguna de estas cosas realmente funcionó. Así que, lo que hice fue ir a mi laboratorio de científico malvado, pensé, así que, conozco Node.js muy bien. Estoy muy familiarizado con sus internos. Debería poder encontrar una solución para esto, ¿verdad? Y sí. ¿Recuerdas cuando hice trabajadores? No los hice solo yo, obviamente otras personas estuvieron involucradas. Pero como esta afirmación, no se siente del todo inexacta. Y, bueno, sí. De todos modos. Entonces, en ese momento, obviamente también di charlas al respecto. Y una de las diapositivas de ese entonces es como, la idea detrás de eso es incrustar Node.js en sí mismo, iniciar una nueva instancia de Node.js, igual que el hilo principal, excepto en un hilo de sistema operativo diferente. Y resulta que, si lo piensas un poco más, ni siquiera necesitas un hilo separado para esto. Puedes hacerlo en el mismo hilo. Esto es algo en lo que he pensado en el pasado por varias razones. Por ejemplo, sistemas de prueba como tap o podrían querer ejecutar fragmentos de código dentro de entornos algo aislados. Tuve conversaciones al respecto. Pensé en qué podríamos hacer con las funciones XSync y similares en Node.js en los procesos secundarios. La forma en que se implementan en Node es que tienen implementaciones completamente separadas de los métodos asíncronos. No hay una buena razón para eso. Y creo que con esto, podríamos reducir bastante la complejidad dentro de Node.js si alguna vez termina en Node.js.

Entonces, la idea es en lugar de tener hilos separados, el bucle de eventos del hilo principal sigue funcionando. Nos da su devolución de llamada. Y dentro de la devolución de llamada o durante el código de inicio, iniciamos un nuevo bucle de eventos, una nueva instancia de Node.js con su propio bucle de eventos en el mismo hilo. Y hasta que hayamos terminado con eso, nada más en el hilo principal avanza. Así que, se me ocurrió, es una pandemia. Estaba un poco aburrido durante las vacaciones. Así que, este es un proyecto que se me ocurrió. Y la idea es, esto es todo lo que necesitas para lograr lo que queremos. Así que creas un trabajador síncrono. Eso es lo que lo llamo porque es como un trabajador en el sentido de que inicia una nueva instancia de Node.js, pero también es como sin multihilo involucrado. Es síncrono.

10. Using Workers for Synchronous IO

Short description:

Puedes crear una función require dentro del trabajador que cargue node fetch. Este es un ejemplo ejecutable. Hay algunas desventajas, como que solo funciona en Node.js y actualmente se implementa como un complemento nativo. Sin embargo, proporciona un control completo del bucle de eventos y acceso a objetos JavaScript. Para el borde de Mongo, usamos Babel para transpilar código asíncrono a código sincrónico. Gracias por escuchar.

Entonces, puedes crear una función require dentro de ese node fetch, dentro de ese trabajador que carga node fetch. Y luego tienes algo, tienes una función fetch que solo se ejecuta dentro del trabajador. Y luego puedes hacer cosas geniales como worker.runLoopUntilPromiseResolved y pasarle una promesa que se creó dentro de este trabajador. Puedes hacer eso dos veces para obtener el texto completo y puedes imprimirlo. Y esto también es, nuevamente, un ejemplo ejecutable.

Hay algunas desventajas. Entonces, es como esto es solo Node.js. Actualmente se implementa como un complemento nativo. Entonces, los navegadores no admiten esto. Y creo que si alguna vez quisieran admitir eso, pasarían años hasta que realmente lo lograran. También es solo Node.js 15.5 y superior porque hubo algunas correcciones de errores que necesitábamos implementar en Node.js en primer lugar. Deberías considerar varias cosas, siéntete libre y siéntete animado a probar algunas cosas con esto, pero probablemente sea muy fácil hacer que el proceso se bloquee al usarlo. Pero obtienes la API completa de Node.js, al igual que en los trabajadores, obtienes un control completo del bucle de eventos y puedes acceder a los objetos JavaScript como cualquier otro objeto JavaScript. Creo que eso es bastante genial. Si te lo estabas preguntando, ninguno de estos métodos realmente funciona para el borde de Mongo porque todos tienen inconvenientes, como viste. Lo que realmente hacemos actualmente es, si recibimos una entrada como esta, donde alguien intenta usar el resultado de una llamada asíncrona de forma sincrónica, lo que hacemos es usar Babel para transpilarlo a código asíncrono y eso funciona lo suficientemente bien para nosotros. También tiene algunas desventajas, como que funciona de la mejor manera posible, estamos usando un peso en lugares donde creemos que debería aplicarse y algunas características del lenguaje no son compatibles, pero en general, esto funciona lo suficientemente bien para nosotros en la actualidad. Gracias por escuchar. Subiré las diapositivas pronto y si tienes alguna pregunta o quieres contactarme en algún momento en el futuro, puedes enviarme un mensaje en Twitter. Gracias. Eso es todo. Hola, hola, ¿cómo estás? Estoy bien. Estoy bien. Estamos muy contentos de que te hayas unido a nosotros. Muchas gracias. ¿Qué opinas de los resultados de la encuesta? Honestamente, tengo que pensarlo un poco porque tengo que repasar en mi cabeza para entender exactamente qué significa el sí y el no. Parece que al menos la mayoría de las personas están usando TypeScript y están muy contentas con eso. Sí, noté que la mayoría de las personas están básicamente contentas con lo que están usando. Pero también tenía curiosidad porque sé que a veces las personas tienen opiniones muy fuertes al respecto y no sé, quería tener una idea de lo que realmente piensan las personas.

11. Migración a TypeScript y Optimizaciones en Node.js

Short description:

En el trabajo utilizamos TypeScript y planeamos convertir el código JavaScript heredado a TypeScript. La migración no es una prioridad máxima en este momento, pero nuestro objetivo es hacerlo por archivo o por proyecto. Seguimos el concepto de desarrollo de una sola marcha, migrando a medida que tocamos cada archivo. En cuanto a las optimizaciones para leer archivos SS en Node.js, mejoré el rendimiento cambiando la implementación para leer el archivo completo de una vez. Ser uno de los principales contribuyentes a NodeJS ha sido una experiencia especial.

Claro, claro. ¿Cuál es tu respuesta a esto? ¿Qué piensas? Sí, bueno, en el trabajo utilizamos TypeScript y estamos muy contentos con eso. Convertir parte de nuestro código JavaScript heredado a TypeScript está en nuestra lista de tareas a largo plazo. Queremos hacerlo en algún momento. Sí. ¿Cómo te está yendo esa migración, o cuál es el plan para eso? Todavía no tenemos un plan, creo. No es una prioridad máxima para nosotros en este momento, pero espero que podamos migrar las cosas por archivo o por proyecto de alguna manera. Sí, sí, sí. Sí, entiendo a lo que te refieres. Va a requerir que alguien dedique mucho tiempo a eso. La empresa para la que trabajo, Buffer, está trabajando actualmente en esta teoría, creo que acuñada por uno de nuestros ingenieros, pero no estoy seguro. Su nombre es Mike Sanderman, y habla sobre el desarrollo de una sola marcha, que básicamente consiste en que a medida que avanzas, cuando tocas un archivo, es cuando haces la migración a la cosa a la que quieres migrar. No estoy seguro de lo fácil que sería eso con TypeScript, pero sí. Así que...

Interesante, interesante. Veamos algunas de las preguntas para ti. Alguien preguntó, ¿qué optimizaciones hiciste para... oh, ¿qué optimizaciones hiciste para leer archivos SS en Node.js mientras te preparabas para la charla? Correcto. Así que, puedo... puedo compartir... Voy a compartir el enlace en el canal de preguntas y respuestas en Discord, pero básicamente, por alguna razón, la implementación promises.readfile en Node lee archivos en pequeños fragmentos de 16 kilobytes. No había una razón real para hacer eso. Especialmente porque obtenía el tamaño del archivo primero. Y cuando sabes que vas a leer el archivo completo, es mejor asignar un búfer grande que sea lo suficientemente grande para contenerlo en lugar de leer pequeños fragmentos una y otra vez. Y así, eso mejora mucho el rendimiento, simplemente cambiando eso. Eso es genial. ¿Puedes hablar... en tu biografía mencionaste que has sido uno de los principales contribuyentes a NodeJS en los últimos cuatro años. ¿Puedes hablar un poco sobre esa experiencia?

12. Experiencias y Consejos sobre Contribuir a Node.js

Short description:

No creo que sea una experiencia que muchos de nosotros tengamos, sinceramente. Estoy muy contento. Aprecio eso mucho. Es muy diferente trabajar en código que afecta a tanta gente y que es tan visible en la comunidad. Tampoco estoy tan triste de no estar trabajando activamente en Node tanto como antes. ¿Tienes algún consejo para aquellos que estén interesados en comenzar a contribuir? Comienza con lo que me gustaría cambiar de Node si pudiera. O ¿qué es algo en lo que sé que podría ayudar? Y luego enfócate en eso en lugar de buscar una contribución fácil. ¿Cuál fue tu primer cambio en Node? Mi primer cambio fue proporcionar un caso de prueba para un error que encontré. No es muy emocionante por sí solo, pero me ayudó a trabajar en mi propio proyecto. Me gusta la filosofía de hacer cambios que sean útiles para ti y probablemente útiles para mucha otra gente.

¿Cómo ha sido para ti? Es una experiencia muy especial. No creo que sea una experiencia que muchos de nosotros tengamos, sinceramente. Estoy muy contento. Aprecio eso mucho. Sí, es muy diferente trabajar en código que afecta a tanta gente y que es tan visible en la comunidad. Tampoco estoy tan triste de no estar trabajando activamente en Node tanto como antes. También implica muchas discusiones largas con mucha gente y muchas opiniones diferentes. Está bien. Es bueno hacer algo diferente de vez en cuando, sinceramente. Cuatro años es mucho tiempo. ¿Tienes algún consejo para aquellos que estén interesados en comenzar a contribuir? Quiero decir, idealmente no comiences con `quiero contribuir`, sino comienza con lo que me gustaría cambiar de Node si pudiera. O ¿qué es algo en lo que sé que podría ayudar? Y luego enfócate en eso en lugar de solo buscar, `hey, ¿cuál sería una contribución fácil?` Porque siempre hay algún pequeño cambio de estilo que puedes hacer. Pero también, si buscas algo que quieres hacer, obtendrás una mayor sensación de logro. Y también, algo más específico de lo que personalmente quieres ver cambiar. Eso es lo que creo. Sí. ¿Cuál fue tu primer cambio en Node? ¿Lo recuerdas? Sí, creo que sí. Entonces, técnicamente mi primer cambio fue proporcionar solo un caso de prueba para un error que encontré. No es muy emocionante, pero muchos de los primeros cambios que hice, oh, sí, mi primer cambio en Node, fue agregar verificación de tipos a setTimeout y otras funciones de tiempo. Y no es muy emocionante por sí solo, pero, hey, esto me ayudó a trabajar en mi propio proyecto que estaba haciendo en ese momento. Así que, eso es realmente genial. Me gusta esa filosofía. ¿Sabes? Hacer los cambios que necesitas o que son útiles para ti. Probablemente útiles para mucha otra gente. Sí, sí.

13. Mejorando Node.js con una API Oficial Soportada

Short description:

Así es como funciona el código abierto. Haces cosas que son buenas para ti y esperas que alguien más también las encuentre útiles. Mucho tiene que ver con el rastreo y la optimización de operaciones en Node. Si logramos tener todo dentro de Node en un formato, podríamos proporcionar una API oficial soportada que te brinde todas las cosas que actualmente mantienen vivo al grupo de eventos. Sería realmente bueno tener algo dentro de Node que sea una API pública completamente soportada. Alguien suficientemente motivado definitivamente podría hacer eso.

Exactamente. Así es como funciona el código abierto. Haces cosas que son buenas para ti y esperas que alguien más también las encuentre útiles. ¿Tenías algo en tu, no sé, en tu lista de tareas personales en lo que deseabas haber trabajado y que alguien esté trabajando en ello ahora mismo? Sí, hay un par de cosas que me hubiera gustado hacer o que me gustaría que alguien haga. Mucho tiene que ver con el rastreo y la optimización de operaciones en Node. Sé que hay personas muy buenas, talentosas y comprometidas trabajando en eso. Pero hay algunas áreas del código que son como, sabes, si logramos tener todo dentro de Node en un solo formato, podríamos hacer cosas realmente geniales, como por ejemplo, proporcionar una API oficial soportada que te brinde todas las cosas que actualmente mantienen vivo al grupo de eventos. Hay algunas internas, y devuelven algunos objetos internos y es muy complicado. Y hay personas que han construido módulos npm sobre eso. Pero sería realmente bueno tener algo dentro de Node que en realidad, ya sabes, sea una API pública completamente soportada. Y creo que alguien suficientemente motivado definitivamente podría hacer eso. Así que si estás viendo esta transmisión en vivo, encuentra la motivación, hay algo que puedes hacer para mejorar este entorno para mucha gente. Quería mencionar, estábamos bromeando sobre esto, pero Ana también vino a Colombia en 2019 para una conferencia. ¿Cómo fue tu experiencia en Colombia? ¿Cuál fue tu cosa favorita? Quiero decir, la cosa favorita fueron definitivamente las personas en la conferencia. Eso no está en duda en absoluto, pero también, fue realmente, realmente genial estar allí en general. Mi pareja siempre se molesta mucho cuando hablo de eso porque estoy presumiendo tanto de que pude ir a Colombia. Sí, no sé. Siempre volvería, realmente fue una de las mejores conferencias a las que he asistido, así que eso... Sí. Eso es tan hermoso. Eso fue, bien. Eso fue increíble. Muchas gracias, Ana. Ha sido muy agradable hablar contigo nuevamente. Gracias por unirte a nosotros. Sí, espero que podamos hablar o tal vez vernos pronto. Sí, esperemos. Que tengas un buen resto de tu día. Adiós.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
Node Congress 2022Node Congress 2022
34 min
Out of the Box Node.js Diagnostics
In the early years of Node.js, diagnostics and debugging were considerable pain points. Modern versions of Node have improved considerably in these areas. Features like async stack traces, heap snapshots, and CPU profiling no longer require third party modules or modifications to application source code. This talk explores the various diagnostic features that have recently been built into Node.
You can check the slides for Colin's talk here. 
JSNation 2023JSNation 2023
22 min
ESM Loaders: Enhancing Module Loading in Node.js
Native ESM support for Node.js was a chance for the Node.js project to release official support for enhancing the module loading experience, to enable use cases such as on the fly transpilation, module stubbing, support for loading modules from HTTP, and monitoring.
While CommonJS has support for all this, it was never officially supported and was done by hacking into the Node.js runtime code. ESM has fixed all this. We will look at the architecture of ESM loading in Node.js, and discuss the loader API that supports enhancing it. We will also look into advanced features such as loader chaining and off thread execution.
JSNation Live 2021JSNation Live 2021
19 min
Multithreaded Logging with Pino
Top Content
Almost every developer thinks that adding one more log line would not decrease the performance of their server... until logging becomes the biggest bottleneck for their systems! We created one of the fastest JSON loggers for Node.js: pino. One of our key decisions was to remove all "transport" to another process (or infrastructure): it reduced both CPU and memory consumption, removing any bottleneck from logging. However, this created friction and lowered the developer experience of using Pino and in-process transports is the most asked feature our user.In the upcoming version 7, we will solve this problem and increase throughput at the same time: we are introducing pino.transport() to start a worker thread that you can use to transfer your logs safely to other destinations, without sacrificing neither performance nor the developer experience.

Workshops on related topic

Node Congress 2023Node Congress 2023
109 min
Node.js Masterclass
Workshop
Have you ever struggled with designing and structuring your Node.js applications? Building applications that are well organised, testable and extendable is not always easy. It can often turn out to be a lot more complicated than you expect it to be. In this live event Matteo will show you how he builds Node.js applications from scratch. You’ll learn how he approaches application design, and the philosophies that he applies to create modular, maintainable and effective applications.

Level: intermediate
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.JS backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
Table of contents- A quick intro to core authentication concepts- Coding- Why passwordless matters
Prerequisites- IDE for your choice- Node 18 or higher
JSNation 2023JSNation 2023
104 min
Build and Deploy a Backend With Fastify & Platformatic
WorkshopFree
Platformatic allows you to rapidly develop GraphQL and REST APIs with minimal effort. The best part is that it also allows you to unleash the full potential of Node.js and Fastify whenever you need to. You can fully customise a Platformatic application by writing your own additional features and plugins. In the workshop, we’ll cover both our Open Source modules and our Cloud offering:- Platformatic OSS (open-source software) — Tools and libraries for rapidly building robust applications with Node.js (https://oss.platformatic.dev/).- Platformatic Cloud (currently in beta) — Our hosting platform that includes features such as preview apps, built-in metrics and integration with your Git flow (https://platformatic.dev/). 
In this workshop you'll learn how to develop APIs with Fastify and deploy them to the Platformatic Cloud.
JSNation Live 2021JSNation Live 2021
156 min
Building a Hyper Fast Web Server with Deno
WorkshopFree
Deno 1.9 introduced a new web server API that takes advantage of Hyper, a fast and correct HTTP implementation for Rust. Using this API instead of the std/http implementation increases performance and provides support for HTTP2. In this workshop, learn how to create a web server utilizing Hyper under the hood and boost the performance for your web apps.
React Summit 2022React Summit 2022
164 min
GraphQL - From Zero to Hero in 3 hours
Workshop
How to build a fullstack GraphQL application (Postgres + NestJs + React) in the shortest time possible.
All beginnings are hard. Even harder than choosing the technology is often developing a suitable architecture. Especially when it comes to GraphQL.
In this workshop, you will get a variety of best practices that you would normally have to work through over a number of projects - all in just three hours.
If you've always wanted to participate in a hackathon to get something up and running in the shortest amount of time - then take an active part in this workshop, and participate in the thought processes of the trainer.
TestJS Summit 2023TestJS Summit 2023
78 min
Mastering Node.js Test Runner
Workshop
Node.js test runner is modern, fast, and doesn't require additional libraries, but understanding and using it well can be tricky. You will learn how to use Node.js test runner to its full potential. We'll show you how it compares to other tools, how to set it up, and how to run your tests effectively. During the workshop, we'll do exercises to help you get comfortable with filtering, using native assertions, running tests in parallel, using CLI, and more. We'll also talk about working with TypeScript, making custom reports, and code coverage.