Flujos de trabajo nativos en Go: un desafío resuelto

Fuentes: How We Built Golang-Native Durable Execution | DBOS

Este artículo de DBOS.dev explora cómo construir una biblioteca de flujos de trabajo en Go que se sienta natural y familiar para los desarrolladores de Go, abordando las limitaciones inherentes al lenguaje en este tipo de tareas. El desafío principal radica en combinar la potencia de Go (soporte para context.Context y un runtime asíncrono eficiente) con sus restricciones en cuanto a tipado. La solución propuesta se centra en la extensión de la interfaz context.Context a través de durable.Context, permitiendo la ejecución duradera de workflows y pasos (steps).

durable.Context se diseña con tres objetivos clave: ofrecer una única interfaz para el usuario, mantener la familiaridad con el context.Context nativo de Go y garantizar la verificación de tipos en tiempo de compilación para workflows y steps. La biblioteca introduce RunWorkflow y RunAsStep como métodos clave para ejecutar funciones Go como workflows o steps, respectivamente. RunWorkflow crea un nuevo durable.Context hijo, gestionando el estado de ejecución y propagando metadatos del workflow. RunAsStep permite integrar funciones existentes, proporcionando seguridad de tipos y facilitando la propagación del contexto duradero. Se aprovechan las funcionalidades de deadline y cancelación del context.Context nativo, permitiendo timeouts y la capacidad de reaccionar a señales de cancelación (aunque no se implementa preemption).

Para superar las limitaciones del sistema de tipos de Go, se utilizan firmas genéricas para Workflow y Step, aunque se prioriza la flexibilidad sobre la estricta seguridad de tipos en algunos casos, utilizando conversión de tipos en tiempo de ejecución para mantener una interfaz única. La biblioteca también aborda el desafío de la serialización de datos (inputs/outputs) para la persistencia, inicialmente utilizando encoding/gob, aunque se identifican desafíos relacionados con el manejo de slices heterogéneos. Un aspecto crucial es la capacidad de mocking, permitiendo a los desarrolladores simular el contexto para pruebas y desarrollo, lo que requiere que los métodos expuestos acepten un contexto como primer argumento. En resumen, el artículo detalla un enfoque pragmático para construir workflows duraderos en Go, equilibrando la potencia, la familiaridad y la seguridad de tipos.