Objetos duraderos sin Cloudflare, sobre la base de datos que ya ejecutas

Fuentes: Durable Objects without Cloudflare, on the database you already run

Solid Objects es una biblioteca de código abierto, publicada bajo licencia MIT, que reproduce el modelo de programación de los Durable Objects de Cloudflare —un objeto monotarea por identidad, con estado persistente y buzón de mensajes— pero sin necesidad de ejecutarse en la infraestructura de un proveedor externo. En lugar de añadir nodos, colas o demonios, la librería aprovecha la base de datos SQL que el usuario ya tiene en producción (SQLite, Postgres o MySQL), de modo que cada objeto es simplemente una fila en una tabla.

El proyecto, obra del desarrollador Lucas Carlson, se distribuye en dos implementaciones que comparten el mismo diseño: una gema para Ruby (que ya funciona en producción en una aplicación con más de 100.000 usuarios) y un paquete para TypeScript/Node. El núcleo de correctness es un turno de ejecución con cuatro pasos: la llamada se inserta como mensaje durable en el buzón del actor; un worker reclama el actor bajo un contrato de arrendamiento (lease) con token de fencing; el código del usuario se ejecuta fuera de cualquier transacción; y, al retornar, una única transacción fenceada guarda el nuevo estado junto con cualquier recordatorio, mensaje saliente o efecto externo encolado por el handler.

La entrega es al-menos-una vez con orden estricto por identidad, por lo que los efectos externos deben ser idempotentes. Un detalle reciente del paquete TypeScript es que todo el runtime puede ejecutarse dentro de una pestaña del navegador. Para validar el diseño, Carlson expone una orden CLI —npm exec solid-objects quickstart— que lanza 25 llamadas concurrentes contra una misma identidad y comprueba con aserciones que se serializan correctamente mientras que identidades distintas avanzan en paralelo. El artículo describe además una prueba deliberada para descartar la escritura tardía de un worker con un lease caducado: dos procesos worker, un lease de 250 ms y un handler que bloquea el event loop durante 2,5 segundos demuestran que la verificación del fencing se ejecuta dentro de la transacción de commit, por lo que la escritura obsoleta nunca llega a persistirse.