1 puntos por GN⁺ 2023-09-29 | 1 comentarios | Compartir por WhatsApp
  • Deno Queues es una cola distribuida serverless construida sobre Deno KV, que permite delegar trabajos largos de forma asíncrona o programar su ejecución para un momento futuro
  • Los desarrolladores solo tienen que poner mensajes con .enqueue() y procesarlos con .listenQueue(), sin necesidad de configurar ni mantener una infraestructura de colas aparte
  • En local usa SQLite, y en Deno Deploy usa FoundationDB; en Deploy, cuando llega el momento de procesar un mensaje, se levanta un V8 isolate on-demand para ejecutarlo
  • El modo de entrega es at-least-once delivery, así que en escenarios de fallas o reintentos el mismo mensaje puede procesarse varias veces
  • No hay un cobro separado por la cola, pero enqueue cuenta como escritura en KV, y la recepción de mensajes se calcula como escritura en KV más una solicitud de Deno Deploy, por lo que conviene considerar tanto el procesamiento duplicado como la estructura de costos

Qué hace Deno Queues

  • Deno Queues es una función de colas basada en Deno KV que permite pasar parte del procesamiento de una aplicación a trabajos asíncronos o programar tareas para ejecutarse más tarde
  • Deno busca reducir la configuración repetitiva y la composición de infraestructura en el desarrollo de software en la nube, ofreciendo bloques base para que los desarrolladores puedan diseñar, mejorar y lanzar más rápido
  • Deno KV es una opción de persistencia basada en FoundationDB y actualmente está en beta abierta
  • Queues ofrece mensajería escalable y administración del procesamiento en segundo plano sobre Deno KV

API básica y forma de ejecución

  • La API principal de Deno Queues tiene dos partes
    • .enqueue(): pone un mensaje nuevo en la cola para entregarlo de inmediato o en un momento futuro
    • .listenQueue(): se usa como handler para recibir y procesar mensajes nuevos desde la cola
  • El flujo básico consiste en abrir KV con Deno.openKv(), enviar un mensaje de Slack en listenQueue y especificar { delay: 60000 } en enqueue para que se procese 60 segundos después
  • El almacenamiento cambia según el entorno de ejecución
    • En ejecución local usa SQLite
    • En Deno Deploy usa FoundationDB
  • En Deno Deploy, cuando un mensaje está listo para procesarse, se ejecuta un V8 isolate on-demand y se despacha el mensaje
  • El código de la aplicación solo necesita recibir mensajes nuevos en el handler listenQueue; Deno Deploy se encarga del resto de la ejecución

Garantía de entrega y reintentos

  • Deno Queues garantiza at-least-once delivery
  • La mayoría de los mensajes enviados con enqueue llaman al handler listenQueue una sola vez, pero en algunos escenarios de falla el mismo handler puede invocarse varias veces para garantizar la entrega
  • Por eso, la aplicación debe manejar de forma segura el procesamiento de mensajes duplicados
  • Si el handler listenQueue lanza una excepción, el runtime reintenta la llamada automáticamente
  • Los reintentos continúan hasta que tenga éxito o se alcance el número máximo de reintentos, cuyo valor predeterminado actual es 5
  • Los mensajes que alcanzan el máximo de reintentos se eliminan

Uso junto con KV atomic transaction

  • Deno Queues puede combinarse con KV atomic transactions
  • Si un mensaje se pone en cola como parte de una transacción de KV, solo entra a la cola si toda la transacción se completa con éxito
  • El flujo de ejemplo verifica y actualiza los saldos de Bob y Liz, y luego encola mensajes de notificación para ambos
    • Se verifica el estado con check(bob, liz)
    • Se reduce el saldo de Bob y se incrementa el de Liz
    • Con enqueue se agregan mensajes de notificación para Liz y Bob respectivamente
    • Solo si commit() tiene éxito se aplican todos los cambios y el encolado
  • También se puede actualizar el estado de Deno KV dentro del handler listenQueue
  • Si se quiere realizar una actualización por mensaje solo una vez, puede construirse un flujo de prevención de procesamiento duplicado guardando y eliminando un nonce
    • Al encolar, se guarda también el nonce
    • Al procesar, si no existe el nonce, se retorna de inmediato
    • Si el procesamiento tiene éxito, se elimina el nonce y se actualizan junto con ello el contador y el estado del saldo

Casos de uso donde la cola encaja bien

  • Las colas permiten que el servidor delegue procesamiento asíncrono y programe trabajos futuros, lo que resulta útil para escalar aplicaciones
  • Notificaciones por correo programadas

    • Cuando una tarea iniciada por el usuario tarda mucho o no hace falta esperar una respuesta de finalización, se puede delegar el trabajo a la cola para mantener la capacidad de respuesta del servidor o de la app
    • En el ejemplo, el mensaje welcome_email se encola de inmediato y el mensaje survey_email se ejecuta con retraso usando { delay: 259200000 }
  • Procesamiento confiable de webhooks

    • Si una solicitud de webhook no se procesa de inmediato y en cambio se pone en cola, puede separarse la respuesta HTTP del procesamiento real
    • Usando Oak junto con Queues, al recibir una solicitud POST a /webhook, el cuerpo de la solicitud se pone en la cola y se devuelve HTTP 200
    • El procesamiento real del webhook se realiza de forma asíncrona en listenQueue con processWebHook
  • Bots de Slack y Discord

    • Queues también puede usarse para crear bots de Discord o Slack
    • El ejemplo de Slack reminder app muestra cómo crear una app sencilla de recordatorios para Slack con Deno Queues
    • El ejemplo de Discord bot usa Deno Queues para crear un giveaway en el que los usuarios pueden participar con un solo clic
    • Se pueden ver más ejemplos de uso de colas en docs.deno.com

Cómo se cobra

  • Deno Queues no tiene un concepto de cobro dedicado por separado
  • El costo se calcula con base en las operaciones de Deno KV y las solicitudes de Deno Deploy
    • Encolado de mensajes: cada operación enqueue equivale a 1 escritura en KV
    • Recepción de mensajes: por cada mensaje recibido se genera 1 escritura en KV y 1 cargo por solicitud
  • La estructura cobra solo por las operaciones realmente usadas

Documentación y roadmap

1 comentarios

 
GN⁺ 2023-09-29
Opiniones de Hacker News
  • Acabo de profundizar en los detalles internos de la versión local de SQLite y recopilé algunas notas: https://til.simonwillison.net/deno/deno-kv#user-content-deno...
    La parte más interesante probablemente sea el esquema que se usa para esta función:
    CREATE TABLE queue ( ts integer not null, id text not null, data blob not null, backoff_schedule text not null, keys_if_undelivered blob not null, primary key (ts, id) );
    CREATE TABLE queue_running( deadline integer not null, id text not null, data blob not null, backoff_schedule text not null, keys_if_undelivered blob not null, primary key (deadline, id) );
    CREATE INDEX kv_expiration_ms_idx on kv (expiration_ms);

    • Me parece que crear 2 tablas con campos casi idénticos y mover filas entre ellas suele ser una mala práctica.
      ¿No están diseñados los índices precisamente para ese tipo de cosas?
    • Desde la perspectiva de un “modelo de negocio open source”, lo especialmente interesante es que Deno está incorporando en las funciones centrales del framework una capacidad que solo su propia plataforma SaaS puede ofrecer bien como actualización a escala global.
      Es algo bastante novedoso, pero también un poco inquietante. Obviamente tienen que comercializarlo, pero no tenía por qué ser de una forma completamente cerrada; para la capa de expansión también podrían haber usado otra licencia como BSL o PolyForm.
  • Creo que la dirección a la que apunta Deno aquí es bastante orientada al futuro.
    Este año empecé a usar Go por primera vez, y parte del lenguaje se parece mucho a C. Además de las diferencias con C, como que gracias al garbage collection se puedan devolver desde funciones valores que parecen punteros asignados en la pila, también incorpora de forma natural funcionalidades integradas como map[string]string. Si se crea un lenguaje nuevo después de 2023, sentí que casi no tiene sentido que no tenga una sintaxis integrada para manejar tipos de mapa.
    Por eso parece lógico que un ecosistema centrado en servidores web cuente con librerías para las funcionalidades primitivas que usamos con frecuencia, y quizá algún día incluso con sintaxis del lenguaje. No recuerdo el último proyecto en el que un servidor web distribuido no tuviera siquiera un almacén clave-valor para caché, un mecanismo de bloqueo o una cola temporal. Un sistema distribuido sin almacén clave-valor se parece vagamente a un lenguaje de programación sin tipo mapa, y es realmente una tecnología tipo navaja suiza.
    El problema potencial es que Deno está recorriendo este camino por su cuenta. Es difícil estar seguro de que las nuevas funciones que Deno está agregando hoy también vayan a estar disponibles en plataformas competidoras y, aunque publiquen la API como open source, al estar en el namespace Deno, no sé si simplemente funcionará cuando quiera cambiar en AWS de FoundationDB a Redis.
    Por eso me da la sensación de que quiero evitar Deno. La sintaxis y las funciones expuestas son realmente atractivas, pero me preocupa tener que hacer una cirugía grande al código después de quedar atado, para poder desplegar en varias infraestructuras cloud. Muchos clientes piden eso. Por ejemplo, si algún día quiero venderle a Oracle o Salesforce y me exigen ejecutarlo on-premise, yo terminaría cargando con el problema de cómo adaptar el almacén clave-valor que puedan usar ellos a las funciones del paquete Deno.
    Es un arma de doble filo. Deno podría lograr empujar esta visión a un público más amplio, pero por ahora creo que lo voy a mirar con cautela.

    • En este caso también está documentado KV Connect, el protocolo de conexión remota: https://github.com/denoland/deno/tree/main/ext/kv#kv-connect
      Probé un poco kv-connect-kit, que implementa este protocolo en TypeScript puro, y ofrece una API de cliente KV en cualquier runtime de JavaScript. Eso incluye Cloudflare Workers, donde no hay ningún namespace de Deno.
      GitHub: https://github.com/skymethod/kv-connect-kit / npm: https://www.npmjs.com/package/kv-connect-kit / deno/x: https://deno.land/x/kv_connect_kit / demo: https://keyspace.deno.dev/
      El protocolo parece funcionar tal como se describe, y escribir otros backends también se ve bastante sencillo.
    • No estoy de acuerdo. Acoplar el runtime del lenguaje con una interfaz KV específica ligada a un servicio de hosting concreto es lo contrario de mirar al futuro.
      La industria tecnológica ha avanzado bastante para alejarse de stacks con lock-in de proveedor, y esto más bien recuerda a esa época.
      No sé cuál es la diferencia práctica entre que Deno.KV venga incluido como parte del runtime y agregar import KV al inicio del archivo. Lo segundo se puede importar desde donde uno quiera, sea Deno o cualquier otro lugar.
      ¿Y qué tan probable es que el equipo de Deno ofrezca bindings para lenguajes que no sean el suyo? ¿También llamaríamos orientado al futuro que Google empezara a meter de forma nativa en Go funcionalidades primitivas exclusivas de Google Cloud?
    • Me gusta Deno, pero por la misma razón me vuelvo cauteloso a la hora de adoptarlo. Para que Deno gane, creo que también tiene que dar soporte completo a sus competidores de hosting.
      Al mismo tiempo, su propio hosting tiene que estar al nivel de los líderes de la industria o ser mejor. Otro camino sería abandonar el hosting propio y ofrecer una solución multicloud con un margen pequeño sobre adaptadores de partners de hosting. Así Deno no tendría que competir directamente como proveedor de hosting.
    • Deno solo está intentando competir con otros SaaS de JS/TS con esto. Vercel/NextJS también tienen un servicio KV, Cloudflare también, y en otros casos está Firebase.
      Más que algo orientado al futuro, me parece una forma de monetizar Deno como SaaS. Es lo que hoy hace cualquiera en el mundo JavaScript con productos de “cloud”: pegarle un framework y revender AWS. Por eso tiene una lista de precios.
      Si el KV de Deno depende de FoundationDB, tampoco parece muy probable que creen activamente adaptadores para otras bases de datos. Cambiar de tecnología de base de datos siempre es un asunto grande, porque cada una tiene usos y características de rendimiento distintos.
    • GC allowing one to return what look like stack allocated pointers from functions no me parece tanto gracias al garbage collection, sino más bien gracias al análisis de escape y a SSA
  • No me convence mucho el argumento de que “para aprovechar la infraestructura de nube pública hay que meterse con código repetitivo y configuraciones complejas, lo que consume mucho tiempo y energía de los desarrolladores”.
    Al final, estamos construyendo infraestructura que debe ser estable. No me parece peor dedicar 30 minutos a configurar una tecnología probada como colas SQS que confiar plenamente en una cola de juguete que Deno creó “sobre SQLite / FoundationDB”. ¿De verdad el costo de 30 minutos de configuración y una mejor “experiencia de desarrollador” valen tanto como para asumir ese riesgo? Para empezar, ¿con qué frecuencia se configura una cola?

    • Creo que esto depende de qué tipo de persona seas.
      Como programador aficionado, no suelo usar grandes proveedores como AWS o Google porque parecen bastante complejos. Si ya estás familiarizado, quizá no sea tan malo.
      También quiero mantener cada proyecto como un repositorio independiente en GitHub. Idealmente, cualquiera debería poder levantar fácilmente la app web en un dominio separado como si fuera su propia app web independiente. Es porque no quiero hacerme responsable de los datos de otras personas.
      Esto se parece en cierta medida a un caso de uso de Sandstorm. Una guía de instalación del tipo “pruébalo localmente y, si quieres usarlo de verdad, crea una cuenta de Deno Deploy” suena bastante razonable.
    • Mucha gente no tiene experiencia con AWS o SQS, e incluso quienes sí la tienen igual deben ocuparse de eso. Deno opta por un enfoque de baterías incluidas para que los desarrolladores puedan tomar algo y usarlo de inmediato.
      Si alguien ofreciera una biblioteca equivalente para la nube, sin duda habría gente que la adoptaría. En el caso de Deno, parece que están identificando problemas comunes que enfrentan los desarrolladores de su ecosistema y empaquetando soluciones razonables para resolverlos.
    • Dicho de forma radical, creo que hoy es mejor no usar colas directamente. Es parecido a usar HTTP/2 puro o administrar hilos manualmente.
      Si usas un motor de workflows que abstraiga las colas, puedes “simplemente escribir código” sin gestionar tareas, programaciones, estado ni reintentos.
      https://www.inngest.com/blog/how-durable-workflow-engines-wo...
      Eso sí, soy autor de un motor de workflows, así que tengo sesgo.
    • Con ese argumento, cualquier cosa nueva es básicamente un “proyecto de juguete” y, como solo AWS está probado, nadie debería lanzar productos nuevos.
    • ¿Cómo sabes que es una cola de juguete?
  • Por mi experiencia previa tratando con “semántica de entrega al menos una vez” y “código de usuario”, los usuarios no entienden bien la entrega al menos una vez.
    En cuanto reenvías un mensaje, empiezan a llover quejas de usuarios e incidentes.
    Creo que habría que lograr lo casi imposible e inventar una semántica de entrega exactamente una vez, o bien reenviar siempre el 0.1% de todos los mensajes para que los usuarios no puedan depender de que se entreguen una sola vez.

    • El SQS inicial era, en la práctica, así. No sé si fue intencional, pero gracias a eso aprendimos rápido que había que respetar los reenvíos.
    • Si los mensajes deben ser idempotentes, recomiendo mucho crear pruebas de integración que garanticen eso desde el lado que envía.
  • Actualmente uso Deno Deploy y, para un proyecto que hago solo, el rendimiento es excelente y es realmente simple.
    Habiendo desarrollado con AWS en equipos grandes, me alegra esta tendencia de alejarse de la complejidad para poder desplegar fácilmente sin pensar en la configuración. El DNS también fue muy sencillo y los certificados SSL automáticos son realmente buenos. No tengo ninguna queja sobre hacia dónde apunta este producto, y me entusiasma su roadmap.

  • Si no se me pasó algo, parece que hay una sola cola por cada instancia de Deno.openKv().
    En la versión local, probablemente puedas crear varias colas llamando a Deno.openKv("db-2.db") con una ruta distinta de archivo SQLite cada vez, pero parece mucho overhead para un requisito bastante común.
    Tal vez sea el estilo arquitectónico de Deno. Al crear apps complejas con Deno, ¿esperan una estructura tipo microservicios donde varios scripts funcionan juntos y cada uno tiene su propio almacén KV y su propia cola?

    • Correcto. Actualmente solo hay una única cola.
      Uno de los desarrolladores principales lo confirmó en Discord: https://discord.com/channels/684898665143206084/115671428253...
      Cito: “Correcto. Actualmente solo admitimos una única cola. Sin embargo, puedes multiplexar múltiples tipos de mensajes en una única cola”.
  • ¿Cómo es el precio?
    Pensaba que Deno era una especie de reemplazo de Node.js; ¿me estoy perdiendo algo? ¿Se puede usar esto localmente o en self-hosting sin costo?

    • Esto funciona igual que el resto de Deno KV. La versión open source usa SQLite, pero si despliegas en el producto de nube de Deno, en su lugar usa FoundationDB propietario.
      Como “Queues are built on Deno KV”, la explicación es que localmente usa SQLite, y en Deno Deploy usa FoundationDB para máxima disponibilidad y throughput.
      Escribí un poco más sobre este patrón aquí: https://til.simonwillison.net/deno/deno-kv
    • Según el artículo, durante el desarrollo local usa SQLite, y al desplegar en Deno pasa a ser parte de las funciones ofrecidas por la nube.
  • Si por casualidad los desarrolladores están leyendo esto, creo que con la excelente usabilidad actual de KV, el lado del control de acceso podría causar dolor más adelante.
    Me pregunto si la solución es simplemente “impleméntenlo ustedes mismos en el espacio de usuario y no introduzcan bugs”, o si hay algo planeado.

    • Me pregunto si te refieres a control de acceso a nivel de usuario, por ejemplo ACL para usuarios autenticados, o a otra cosa. Si compartes ideas más extensas, mantendremos esta preocupación presente.
  • El soporte reciente para Jupyter y esta función de colas me entusiasman. Son cosas realmente geniales.
    Pero no creo que vaya a escribir servidores con Deno y ponerlos en producción en mi propio servidor. No me gusta serverless.
    Los modelos de negocio de Deno y Bun están construidos alrededor de serverless, es decir, Deno Deploy. Y Deno Deploy es otro runtime.
    Eso queda claro con KV y las colas. En local o en self-hosting, tienes una versión que apenas funciona montada sobre otras tecnologías.
    Es decir, terminarías haciendo self-hosting de una versión de Deno distinta de la que usa la mayoría de los clientes de Deno.
    ¿Cuánta gente usará Deno para correr servidores en su propio hardware? Si ese número es bajo, mejor usaría Node.

  • Deno es realmente interesante. Es excelente que tenga un modelo de negocio viable, buena usabilidad y nada de tareas inútiles de configuración.

    • Intenté entusiasmarme con Deno, pero no lo tengo claro. No veo qué lo diferencia de todo lo que ya se ha hecho innumerables veces en el pasado.
      Deno en sí es, en esencia, Node.js con compilación automática de TypeScript. En condiciones normales, solo habría hecho falta un archivo de configuración más. Cuando salió el proyecto, se destacó mucho que permitía alejarse del ecosistema desordenado de NPM, pero al final tuvieron que dar marcha atrás y agregar soporte para NPM, y esa diferenciación también desapareció.
      Deno Deploy es igual a las decenas de servicios tipo Lambda que ya existen. El almacenamiento KV y ahora las colas están al nivel de Redis, LevelDB, RocksDB, Dynamo, SQS o muchísimas opciones similares. Todavía no he visto ni una sola función que realmente diferencie a Deno del resto.
      Si prefieres que una sola empresa se encargue del runtime del lenguaje, el hosting de cómputo y el almacenamiento de datos, puede resultar atractivo. Pero personalmente preferiría evitarlo, sobre todo si esa empresa no tiene trayectoria en ese campo.
    • ¿Qué te hace creer que Deno tiene un modelo de negocio viable?