El camino hacia el contexto asíncrono

Rate this content
Bookmark

La API AsyncLocalStorage es sin duda una de las adiciones más importantes y relativamente recientes a Node.js. Hoy en día estamos viendo implementaciones que se agregan a otras ejecuciones como workerd, deno y bun. Y hay un esfuerzo en marcha en TC-39 para introducir una nueva API de AsyncContext al lenguaje. Esta charla presentará el seguimiento del contexto asíncrono con AsyncLocalStorage y AsyncContext y discutirá cómo el modelo está evolucionando a medida que se implementa en múltiples plataformas.

26 min
14 Apr, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Esta charla discute la implementación y mejoras de rendimiento de la API de almacenamiento local asíncrono en Node y Cloudflare Workers. Explora el concepto de continuaciones y contextos de ejecución y cómo el almacenamiento local asíncrono permite pasar datos contextuales a través de flujos asíncronos. La charla también destaca los desafíos en la implementación del almacenamiento local asíncrono en Node y la necesidad de una API estandarizada. Se discute la introducción del contexto asíncrono como reemplazo del almacenamiento local asíncrono, junto con sus beneficios y el desarrollo continuo de la API de contexto asíncrono.

Available in English

1. Introducción a Async Local Storage

Short description:

Hablaré sobre código en Node, Cloudflare Workers y la API de almacenamiento local async. Hemos estado trabajando en mejorar su implementación y rendimiento en Workers. Además, discutiré las diferencias entre Node y Workers y la próxima API de Async Context. El almacenamiento local async crea una tienda que se mantiene coherente a través de operaciones async utilizando contextos de ejecución y continuaciones.

Buenos días, ¿cómo están todos? Cuando me invitaron a subir y hablar, estaba pensando en qué quería hablar Sabes, podríamos hablar de Node en general, de lo que está sucediendo en el proyecto. Y solo quería hablar de código.

Así que, sabes, quiero hablar sobre parte del código que hemos estado escribiendo recientemente, hemos estado trabajando no solo en Node, sino también en Cloudflare Workers y la API de almacenamiento local async. Si no estás familiarizado con ella, ha estado en Node durante un par de años, pero no es muy conocida en cuanto a lo que hace y cómo funciona. Y una de las cosas que, sabes, mientras comenzamos a trabajar en esto en Workers recientemente como parte de nuestra historia de compatibilidad con Node, tratamos de averiguar cómo está implementado, cómo, sabes, es el rendimiento y cómo está escrito. ¿Es lo que debería ser? Bien.

En Workers, decidimos tomar un enfoque de diseño diferente en cómo funciona bajo los covers y quiero hablar sobre las diferencias entre cómo funciona en Node, cómo funciona en Workers y hacia dónde se dirigen las cosas. Ahora, sabes, ese título original de la charla, el Camino hacia Async Context. Async context es en realidad una nueva API estándar propuesta que cubre el mismo caso de uso que almacenamiento local async, pero en realidad se agregará al propio lenguaje. Y hablaré un poco sobre eso al final. Un poco más sobre mí, sabes, para aquellos de ustedes que no me conocen He estado involucrado con Node durante varios años. También estoy contribuyendo a CloudFlare Workers. En realidad, soy parte del equipo de tiempo de ejecución de Workers en CloudFlare. No voy a hablar demasiado sobre Workers en sí. Mi colega Matt Alonzo está aquí. Mostrará algunos detalles y aspectos más específicos de Workers. Si estás interesado en eso, te recomiendo que vayas a su charla más tarde. Bien, empecemos. ¿Qué es el almacenamiento local async? La documentación de Node nos da esta definición muy útil. Crea una tienda que se mantiene coherente a través de operaciones async. Eso es básicamente todo. Y luego te da un ejemplo. Es una explicación extremadamente inútil de lo que es. Así que lo vamos a desglosar un poco más. Bien, tenemos esta noción de lo que se llama un contexto de ejecución. Esto es cualquier código que se está ejecutando en este momento. Ese contexto de ejecución puede programar una continuación. Una continuación es cualquier código que se programa para ejecutarse más tarde. Piensa en un temporizador o una promesa. Cada vez que adjuntas un then, un catch, un finally a ella. Callbacks.

2. Comprensión de Continuaciones y Contexto de Ejecución

Short description:

Cuando llamas a la API de FS y se ejecuta el callback async más tarde, la continuación es el término genérico para las cosas programadas para ejecutarse más tarde. El contexto de ejecución puede programar cualquier número de estas cosas, como QMicroTask, promesas, callbacks o process next take.

Entonces, cuando llamas a la API de FS y se ejecuta el callback async más tarde. Sabes, la continuación es más o menos el término genérico para esas cosas que están programadas para ejecutarse más tarde. ¿De acuerdo? De acuerdo. Entonces, a medida que el contexto de ejecución se está ejecutando, puede programar cualquier número de estas cosas, ¿verdad? Sabes, si estás usando QMicroTask, promesas, callbacks o process next take. Todas estas cosas son cosas que el código actual, el código en ejecución actual, puede programar para ejecutarse, ya sabes, en unos momentos, más tarde, ya sabes, en algún momento posterior en la aplicación. Lo que sea. Pero estas cosas pueden acumularse.

3. Comprensión de Async Local Storage

Short description:

Async local storage nos permite asociar datos contextuales con continuaciones. Podemos registrar identificadores de solicitud únicos sin pasarlos explícitamente a través de cada función. Esto simplifica en gran medida el paso de información, especialmente cuando no controlamos la API.

El almacenamiento local asíncrono se trata de poder asociar data contextual con la programación de esa continuación, ¿verdad? Entonces, cuando el contexto de ejecución actual se está ejecutando, queremos poder establecer un valor de contexto. Y luego, cuando esa función realmente se ejecute más tarde, queremos poder recuperar ese mismo valor exacto, ¿verdad?

Un ejemplo hace que esto sea mucho más fácil de entender. Muy bien. En este caso particular, lo que queremos, esta función de registro en la parte superior es nuestro caso de uso. Lo que queremos es poder registrar algo en la consola que tenga un identificador de solicitud único. ¿De acuerdo? Así que imagina que esto es un servidor. Cada vez que llega una solicitud, queremos crear un ID único para esa solicitud. Y cada vez que tenemos la salida del registro de la consola, queremos incluir ese ID único en esa salida. ¿De acuerdo?

La forma en que tenías que hacerlo hasta que existía el almacenamiento local esencialmente era pasar ese ID explícitamente a través de todas tus funciones. ¿De acuerdo? O tenías que adjuntarlo a algo más. Probablemente todos hemos visto el caso en el que tomas el objeto de solicitud y agregas propiedades y lo pasas así. Eso es muy desagradable. Agregar propiedades arbitrarias a un objeto de otra persona que no posees siempre es un poco problemático. ¿De acuerdo? Y además, tener que pasar esta propiedad por cada función, incluso si no la vas a usar, solo para poder tener algo como el registro, es muy engorroso, muy difícil de hacer, especialmente si no controlas ese código. ¿De acuerdo? Todas esas funciones por las que tienes que pasar, si no controlas eso, hace que sea mucho más difícil de hacer. ¿De acuerdo? Entonces, ya sabes, esto muestra un poco más de la complejidad aquí. Como en todas partes a donde va esa cosa, esta función de hacer algo y hacer algo más, en realidad no estamos usando el ID allí. La única razón por la que tenemos que pasarlo es para poder llegar a ese registro. ¿De acuerdo? Con el almacenamiento local asíncrono tenemos un modelo mucho mejor. ¿De acuerdo? Podemos crear esta instancia de almacenamiento local asíncrono en un ámbito que sea visible tanto para, ya sabes, el servidor como para nuestra función de registro. ¿De acuerdo? Los métodos de hacer algo y hacer algo más no necesitan saber nada sobre este ID. ¿De acuerdo? A medida que establecemos, a medida que, ya sabes, vamos y comenzamos a lidiar con nuestra solicitud, ¿verdad? Le decimos al ID de solicitud cuál será ese valor. Esto está configurando un contador que se incrementa en cada solicitud. Y luego llamamos a set timeout. Solo estamos simulando actividad asíncrona aquí. Va a esperar un poco de tiempo. Luego, cuando realmente llama a esa función, esa función de hacer algo, que luego hace el registro. Dentro del registro, extraeremos ese valor almacenado del ID de solicitud y seguiremos adelante. Entonces, simplifica en gran medida cómo pasamos realmente esta información. Como dije, especialmente cuando no controlamos esa API por la que estamos pasando.

4. Almacenamiento Local en Node.js

Short description:

El almacenamiento local asíncrono te permite pasar datos contextuales a través de flujos asíncronos. Está construido sobre las APIs de ganchos asíncronos y ganchos de promesas, lo que agrega complejidad y pérdida de rendimiento. Cada instancia de almacenamiento local asíncrono tiene una clave oculta que representa esa instancia de API. En Node, hay un recurso de ejecución actual que representa el código en ejecución. Establecer un valor en el almacenamiento local asíncrono establece la clave en el mapa del recurso de ejecución actual. Esta copia de valores entre recursos puede ser costosa y resultar en pérdida de rendimiento. La implementación de Node se basa en los ganchos asíncronos, originalmente diseñados como una API de diagnóstico.

¿Verdad? Entonces, si este hacer algo es de algún módulo arbitrario de terceros en NPM que no controlas la API, pero aún necesitas que se pase ese ID y aparezca en tus registros, el almacenamiento local asíncrono es lo que hará eso posible para ti. ¿Verdad? Te permitirá obtener esa información. Esto es a lo que nos referimos con mantener la coherencia. Está ahí cuando lo necesitas en ese flujo asíncrono. ¿De acuerdo?

Podemos establecer varias cosas, ¿verdad? Entonces, este almacenamiento local asíncrono no es solo un valor único. Puedes programar tantas continuaciones como desees al mismo tiempo, con valores diferentes. Cuando se ejecuten, y pueden ejecutarse en cualquier orden, se devolverá el valor apropiado cuando llames a als.getStore. ¿De acuerdo?

Pero, ¿cómo lo hacemos? Desafortunadamente, es un poco complicado en Node en este momento. El almacenamiento local asíncrono se basa en una API llamada ganchos asíncronos y ganchos de promesas. Hablaremos un poco más sobre eso en un momento. Pero agrega un cierto grado de complejidad y pérdida de rendimiento cuando realmente lo usamos. Cada instancia de almacenamiento local asíncrono tiene una clave. Y es una clave oculta dentro de esa instancia que representa esa instancia particular de esa API. Y luego, en cualquier momento dado dentro de Node, tenemos esta cosa llamada recurso de ejecución actual. Ese es el objeto que representa el código que se está ejecutando en este momento. Entonces, cuando se dispara un temporizador, ese recurso de ejecución actual es un temporizador. Cuando estás lidiando con una promesa, entonces una continuación de promesa, ese recurso de ejecución actual es una promesa. Siempre hay un objeto que representa ese código en ejecución actual dentro de Node, ¿verdad? Cada vez que estableces ese valor, entonces als.run, ¿verdad?, y establecemos ese valor, lo que hacemos es establecer esa clave de esa instancia en el valor que estamos estableciendo. Y ese recurso de ejecución actual mantiene el mapa de todos esos valores. Digamos que tenemos 10 instancias de almacenamiento local asíncrono en nuestra aplicación, en ese recurso de ejecución actual habrá 10 claves, 10 valores diferentes, ¿verdad? Cada vez que programamos algo nuevo, un nuevo temporizador, una nueva continuación de promesa, cada vez que agregas un nuevo then, cada vez que creas una nueva promesa, lo que hacemos ahora es tomar el conjunto completo de esas propiedades y copiarlas al nuevo recurso. Pero piensa en el costo de rendimiento de eso. He trabajado con aplicaciones en producción que han creado decenas de miles de promesas en solo unos segundos. Cada vez que se crea una nueva promesa en este modelo, este contexto asíncrono aquí, esas claves valores se copian de un objeto al siguiente. ¿Verdad? Esa es una operación increíblemente costosa. He visto casos en los que simplemente activar el almacenamiento local asíncrono en una aplicación pesada ha sido una pérdida de rendimiento del 30 al 50%. Y eso es ser bastante conservador. ¿Verdad? Podemos hacerlo mejor. Como dije, la implementación de Node se basa en ganchos asíncronos y ganchos de promesas. Los ganchos asíncronos fueron originalmente destinados como una API de diagnóstico. Es una forma de monitorear el ciclo de vida de estos recursos asíncronos que se crean dentro de Node.

5. Entendiendo el Contexto Asíncrono y su Implementación

Short description:

Pero es algo muy básico e interno. Promise hooks es una API integrada en v8, realmente destinada a ayudar con este tipo de casos de uso. Un problema clave aquí es que estamos propagando ese contexto. Recientemente implementamos el almacenamiento local asíncrono en Cloudflare Workers. Introdujimos esta cosa llamada un marco de contexto asíncrono.

Pero es algo muy básico e interno. Se descubrió cuando comenzamos a analizar el almacenamiento local asíncrono, como, hey, podríamos usar esto para implementar este modelo. pero su rendimiento es realmente pobre.

Promise hooks es una API integrada en v8, realmente destinada a ayudar con este tipo de casos de uso. Lo que hace es configurar una serie de devoluciones de llamada que se pueden activar cuando se crea una promesa, cuando se resuelve, cuando ocurren todos los diferentes eventos del ciclo de vida de esa promesa. Pero eso se vuelve extremadamente costoso cuando invocas ese código cada vez que creas una promesa, cada vez que resuelves la promesa. Y como dije, las aplicaciones pueden crear decenas de miles, incluso cientos de miles de promesas en solo unos momentos de tiempo. Por lo tanto, ese código termina siendo extremadamente costoso de ejecutar cada vez.

Un problema clave aquí es que estamos propagando ese contexto. Estamos copiando esos pares clave-valor de un recurso de ejecución a otro. Cada vez que se crea una de esas continuaciones, no cuando el contexto realmente cambia, ¿verdad? Y eso es lo importante porque la información contextual real con la que estás tratando solo cambia muy, muy raramente, ¿verdad? Solo estás tratando con unas pocas instancias de estas cosas. Los valores generalmente se establecen una vez durante la aplicación. Ahora mismo, cada vez que creamos esas promesas, estamos copiando esos datos cada vez y se vuelve muy, muy costoso muy rápidamente.

Recientemente implementamos el almacenamiento local asíncrono en Cloudflare Workers. Esto es algo divertido. En realidad, no vamos a tener compatibilidad total con Node en Workers, pero tendremos cosas como node dot o node colon F o no FS, pero node colon net y node colon crypto, y muchas de estas cosas, estamos usando el especificador de nodo allí. Es obligatorio, al igual que en Dino. Está ahí. Y el almacenamiento local asíncrono es uno de los primeros que agregamos. Acaba de habilitarse, creo que el mes pasado, y está disponible para que todos lo usen. Pero lo hicimos sin usar async hooks o promise hooks. Pero a nivel de API, lo que usa el código es muy compatible con lo que tiene Node, pero lo hemos implementado de una manera completamente diferente.

Entonces, ¿cómo lo hacemos? Introdujimos esta cosa llamada un marco de contexto asíncrono. En lugar de almacenar todos esos pares clave-valor en el recurso de ejecución real, lo que hacemos es crear un marco solo cuando el dato realmente cambia. Entonces, inicialmente, cuando la aplicación se está ejecutando, no hay marco. No hemos establecido ningún valor. La primera vez que se utiliza una instancia de ALS, crearemos un marco y estableceremos ese valor y ese marco realmente mantiene ese mapa. El recurso de ejecución solo mantiene una referencia al marco actual. Entonces, cuando se crea ese recurso, simplemente lo vincularemos al marco actual. Solo creamos nuevos marcos cuando se especifica un nuevo valor.

6. Desafíos de Implementación y Estandarización

Short description:

Entonces es mucho menos costoso. Solo estamos propagando ese contexto cuando los valores realmente cambian, no cuando se programan las continuaciones individuales. Esto es cómo lo hacemos actualmente en Workers. Esto es cómo quiero hacerlo en Node. Hay un desafío con cómo podemos implementar esto en Node en este momento. Todo esto depende de una nueva API. Es una API que ha estado en V8 durante años y que estamos utilizando. Elimina por completo cualquier dependencia de los ganchos asíncronos y los ganchos de promesa para implementar todo este modelo. Lo que espero es que más adelante este año, realmente podamos hacer estos cambios en V8 y lograr una mejora significativa en el rendimiento en Node, para cualquiera que esté utilizando la API de almacenamiento local asíncrono. Entonces, ¿qué hay de la estandarización? Hace un tiempo, Luca, que trabaja en Dino, publicó este comentario en Twitter, lo encontré bastante divertido. Vercel ha adoptado el almacenamiento local asíncrono, otras personas están comenzando a adoptarlo. Entonces, ¿qué deben hacer estos entornos de ejecución? ¿Dino y Workers y Bun, simplemente implementan, siguen el ejemplo de Node e implementan todas las API específicas de Node? Bueno, resulta que sí, estamos haciendo eso. Estamos implementando esa capa de compatibilidad con Node, pero lo que realmente queremos son estándares, una API estándar para esto. Afortunadamente, TC39 está trabajando en esto. Hay una API de contexto asíncrono que se está desarrollando activamente en este momento. Está en la etapa dos.

Entonces es mucho menos costoso. Solo estamos propagando ese contexto cuando los valores realmente cambian, no cuando se programan las continuaciones individuales. Esto resulta en una mejora masiva de rendimiento. Esto es cómo lo hacemos actualmente en Workers. Esto es cómo quiero hacerlo en Node.

Me salté algunas diapositivas aquí, pero hay un desafío con cómo podemos implementar esto en Node en este momento. Todo esto depende de una nueva API. Es una API que ha estado en V8 durante años y que estamos utilizando. Es poco documentada, muy pocas personas realmente conocen esta API. Elimina por completo cualquier dependencia de los ganchos asíncronos y los ganchos de promesa para implementar todo este modelo.

El problema es que Chromium también utiliza esta API. La forma en que está diseñada actualmente, solo se puede usar para un propósito a la vez. Si Node fuera solo Node, sin depender de Chromium en absoluto, solo por sí mismo, estaría bien. Podríamos usarlo. Pero hay cosas como Electron que usan tanto Node como Chromium, y están utilizando la misma instancia de V8. Dado que Chromium también está utilizando esta API de su propia manera, no podemos usarla en Node todavía, hasta que hagamos cambios en V8 para que funcione. El cambio clave que necesitamos hacer para que funcione es permitir múltiples usos de esta API al mismo tiempo, para poder establecer estos datos contextuales y tener múltiples claves. Así que es algo que está por venir. Lo que espero es que más adelante este año, realmente podamos hacer estos cambios en V8 y lograr una mejora significativa en el rendimiento en Node, para cualquiera que esté utilizando la API de almacenamiento local asíncrono. En este momento, el rendimiento es el principal problema con el que te encontrarás si estás utilizando esta API. ¿De acuerdo?

Entonces, ¿qué hay de la estandarización? Esta es una muy buena pregunta. Hace un tiempo, Luca, que trabaja en Dino, publicó este comentario en Twitter, lo encontré bastante divertido. Vercel ha adoptado el almacenamiento local asíncrono, otras personas están comenzando a adoptarlo. Entonces, ¿qué deben hacer estos entornos de ejecución? ¿Dino y Workers y Bun, simplemente implementan, siguen el ejemplo de Node e implementan todas las API específicas de Node? Bueno, resulta que sí, estamos haciendo eso. Estamos implementando esa capa de compatibilidad con Node, pero lo que realmente queremos son estándares, una API estándar para esto. Afortunadamente, TC39 está trabajando en esto. Hay una API de contexto asíncrono que se está desarrollando activamente en este momento. Está en la etapa dos.

7. Introducción a Async Context

Short description:

El ejemplo con almacenamiento local asíncrono cambia a contexto asíncrono. Las diferencias de API son mínimas para el caso de uso más común. La propuesta está en desarrollo activo y se espera que se agregue pronto. Las características como enter with y disable no se incluirán. Se ha creado un subconjunto portátil interoperable web para garantizar la compatibilidad futura con Async Context. El objetivo es implementar esto en varios JavaScript Runtimes.

Y para tener una idea de cómo se verá esto, este es el ejemplo con almacenamiento local asíncrono ahora, y así es como cambia con el contexto asíncrono. ¿Correcto? Entonces simplemente cambiamos new async local storage a new async context y get store simplemente se convierte en get. ¿Correcto? Será tan simple como eso.

Hay algunas otras diferencias de API más pequeñas dependiendo de lo que estés haciendo, pero para el caso de uso más común, este es el alcance del cambio. ¿De acuerdo? Muy, muy sencillo. El código QR te lleva al repositorio de GitHub donde se está trabajando en esta propuesta. Actualmente está en desarrollo activo. Está en la etapa dos. Se espera que pase a la etapa tres un poco más adelante este año, con muchas preguntas sin respuesta, cosas en las que todavía están trabajando. La mayor parte de la API, sin embargo, es estable, pero está en camino de ser agregada pronto.

Si tienes interés en esto, están buscando más aportes sobre casos de uso y preguntas generales sobre cómo se va a utilizar. Pero, como dije, la API simple está bastante cerca. Hay algunas características del almacenamiento local asíncrono que no estarán en el contexto asíncrono. Específicamente cosas como enter with y disable. Lo que permiten estas API es modificar la información contextual en su lugar sin - con run, run creará ese nuevo marco, enter with modifica ese marco tal como existe. Por lo tanto, ese marco de contexto se vuelve completamente mutable de forma síncrona. Eso tiene varios desafíos. Azure actualmente lo permite. Es una función experimental, pero eso no se llevará a Async Context por varias razones. Así que simplemente no uses esas. No uses esas características. Y de hecho, como parte de WinterCG, creamos lo que llamamos un subconjunto portátil interoperable web. Básicamente, es solo el subconjunto de la API de almacenamiento local asíncrono que puedes usar hoy y ser compatible con Async Context cuando salga. Y el objetivo aquí es implementar esto no solo en Node, que ya está allí, sino implementarlo en Workers. Nos gustaría verlo implementado en Deno. Nos gustaría verlo implementado en Bun. Nos gustaría verlo implementado en todos los JavaScript Runtimes que existen. Y estamos trabajando activamente con esos Runtimes para que analicen este subconjunto e implementen esto, antes de que llegue Async Context.

Eso es todo. Espero que haya sido útil.

QnA

Q&A sobre Async Local Storage

Short description:

La gente tiene preguntas sobre esto, solo avísenme. Gracias. Gracias James. Eso fue genial. ¿Tenemos alguna pregunta? La primera es, ¿cómo tienes una barba tan genial? Cuando conocí a mi esposa, era solo una barba corta, y ella me dijo que no me afeitara, así que la tengo. La siguiente pregunta es, ¿no crearía un concurso de sinks un estado global con su propio conjunto de propagación en parámetros? ¿Vale la pena el intercambio? La respuesta corta es sí. Puede suceder. Si estableces el contexto asíncrono en ese estado global, entonces sí, tiene todos los mismos problemas que el estado global en general. La siguiente pregunta es, el contexto asíncrono está en la etapa 2, ¿hay algún tipo de resistencia en cuanto a seguridad que pueda evitar que esto se implemente? Sí. En cuanto a la resistencia, la API es bastante estable. Ha habido algunas preguntas de seguridad en el comité. Pero según lo que he entendido, esas preguntas se han resuelto y ha sido bien aceptado. Y ¿por qué el almacenamiento local asíncrono copia pares clave-valor en lugar de hacer lo mismo que hiciste? Es difícil de decir. Dado que todo se construyó sobre la API de ganchos asíncronos, hay algunas limitaciones en cómo funciona eso. Hay bastante complejidad involucrada en el seguimiento de esos recursos. Y el hecho de que estemos lidiando con muchos tipos diferentes de recursos, promesas y temporizadores y todas esas cosas, fue lo más fácil de hacer en el modelo actual.

La gente tiene preguntas sobre esto, solo avísenme. Gracias. Gracias James. Eso fue genial. ¿Tenemos alguna pregunta?

Así que tenemos algunas preguntas para ti, la primera es, ¿cómo tienes una barba tan genial? Cuando conocí a mi esposa, era solo una barba corta, y ella me dijo que no me afeitara, así que la tengo. Fue hace bastante tiempo, en 2012. 2012, no te has afeitado ni una vez. No me he afeitado en mucho tiempo, tengo que mantener a mi esposa feliz.

La siguiente pregunta es, ¿no crearía un concurso de sinks un estado global con su propio conjunto de propagación en parámetros? ¿Vale la pena el intercambio? La respuesta corta es sí. Puede suceder. Si estableces el contexto asíncrono en ese estado global, entonces sí, tiene todos los mismos problemas que el estado global en general. Puedes establecer ese almacenamiento local asíncrono o el contexto asíncrono en cualquier ámbito que desees. Solo tiene que ser accesible para las funciones que lo necesiten. Así que no tienes que hacerlo como un global. La mayoría de los ejemplos lo muestran como un global. Genial. Sigo haciendo tus preguntas, por favor.

La siguiente pregunta es, el contexto asíncrono está en la etapa 2, ¿hay algún tipo de resistencia en cuanto a seguridad que pueda evitar que esto se implemente? Sí. En cuanto a la resistencia, la API es bastante estable. Ha habido algunas preguntas de seguridad en el comité. Pero según lo que he entendido, esas preguntas se han resuelto y ha sido bien aceptado. La pregunta clave que se está haciendo en este momento es si realmente pertenece al lenguaje o si debería ser implementado como una API de la plataforma web a través de WG o W3C, uno de esos lugares. Ese es el debate clave que está ocurriendo en este momento. Y todavía hay algunos argumentos muy buenos en contra de que se incluya en el lenguaje. Genial. Y ¿por qué el almacenamiento local asíncrono copia pares clave-valor en lugar de hacer lo mismo que hiciste? Es difícil de decir. Dado que todo se construyó sobre la API de ganchos asíncronos, hay algunas limitaciones en cómo funciona eso. Hay bastante complejidad involucrada en el seguimiento de esos recursos. Y el hecho de que estemos lidiando con muchos tipos diferentes de recursos, promesas y temporizadores y todas esas cosas, fue lo más fácil de hacer en el modelo actual.

Q&A sobre el Contexto Asíncrono

Short description:

Los autores de la propuesta de contexto asíncrono han descartado implementar la funcionalidad nterwith. Utilice el almacenamiento local asíncrono y adhiera al subconjunto portátil definido por WinterCG. La API de ganchos asíncronos no está obsoleta, pero es mejor evitarla en la mayoría de los casos de aplicación. Existen similitudes entre DinoKV y KV2 de los workers, y más casos de uso para el almacenamiento local asíncrono incluyen APM, trazado y registro. La relación del contexto asíncrono con el contexto asíncrono de Java es desconocida.

No fue la forma más eficiente de hacerlo, pero creo que terminó siendo la más fácil. ¿Hay alguna posibilidad de que nterwith se pueda implementar en la propuesta? ¿Es básicamente necesario para APM ya que a veces no podemos decidir si estamos en modo SYNC o asíncrono? Sí, probablemente no. En este momento, los autores de la propuesta de contexto asíncrono lo han descartado por completo y dicen que no quieren admitir esa funcionalidad de nterwith. No sé si volverá más adelante, no lo veo.

Tenemos más preguntas para ti. Tenemos dominios que están obsoletos y almacenamiento local asíncrono que es experimental. ¿Cuál debería usar ahora si lo necesito? Así que use el almacenamiento local asíncrono ahora, adhiérase a ese subconjunto portátil que ha definido WinterCG. Eso será, si se adhiere a ese subconjunto cuando se termine el contexto asíncrono, Node admitirá ambos, los workers admitirán ambos, con suerte Dino admitirá ambos. Así que tiene una mayor probabilidad de ser compatible si se adhiere a ese subconjunto. La API de ganchos asíncronos, no está obsoleta tanto como que es permanentemente experimental y a nadie le gusta. Tiene algunos casos realmente buenos para fines de diagnóstico y puede usarlo para esas cosas, pero en la mayoría de los casos de aplicación es mejor evitarlo.

Genial. Acabas de mencionar a Dino. Tenemos una pregunta sobre Dino. ¿Ves algunas similitudes con DinoKV? Oh sí, sí. Estoy muy interesado en DinoKV. En los workers, tenemos KV2 y voy a investigar eso mucho más en detalle. Bueno, no hay comentarios al respecto todavía. Sorpresa. ¿Puedes darnos más casos de uso interesantes además del registro? Eso es interesante. Las personas que trabajan en la propuesta de contexto asíncrono están luchando por encontrar más casos de uso además de cosas como trazado y registro, pero si observas la mayoría de las... Si observas la mayoría de las aplicaciones que usan el almacenamiento local asíncrono ahora... Son cosas como APM, trazador y registro... Esos son los casos de uso clave. Así que, ya sabes, estamos buscando más, pero esos son los que hemos visto más. El trazado es uno importante. ¿El contexto asíncrono está relacionado o inspirado en el contexto asíncrono de Java? Esa es una buena pregunta. No lo sé.

Beneficios de migrar a Async Context

Short description:

El contexto asíncrono está inspirado en el almacenamiento local asíncrono y beneficiará a todas las aplicaciones. Se recomienda usar ALS ahora y migrar a async context cuando esté disponible. Las diferencias en los modelos y la API son mínimas. Es especialmente útil para servidores con un contexto único para cada solicitud.

¿No? Lo descubriremos más adelante... Está principalmente inspirado en el almacenamiento local asíncrono.

¿Y qué tipo de aplicaciones se beneficiarán al migrar a async context desde ALS? Creo que todas. Entonces ALS es lo que tienes disponible ahora. Es lo que debes usar ahora. Cuando async context esté disponible, no habrá ninguna razón para no usarlo y no migrar a él. Como dije, los modelos serán muy similares, muy cercanos. Las diferencias en la API serán mínimas. Así que no habrá ninguna razón para evitarlo.

Los tipos de aplicaciones, servidores, principalmente serán más útiles para servidores que tienen ese contexto único para cada solicitud. Bueno, no tenemos más preguntas, pero gracias y démosle una pluma.

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
Top Content
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
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.
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 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.