¿Qué son las Funciones Durables de Azure?
Contexto
Serverless y Function as a Service han sido buzzwords desde ya hace algunos años. Cualquier desarrollador o arquitecto de software ha escuchado acerca de éste tema, o implementado alguna aplicación utilizando algún patrón de arquitectura serverless.
Es importante mencionar que no debemos confundir las arquitecturas de microservicios con las arquitecturas serverless, ya que ambas si bien tienen algunas similitudes, también son diferentes en cuanto a los casos de uso en los que se aplican.
Algunos ejemplos de patrones de arquitectura serverless son:
- Distribución de procesos de entrada y salida(Fan-in and Fan-out)
- De Agregación o Aggregator
- Procesamiento de datos basado en eventos
- Aplicaciones web serverless o Serverless web apps
- Flujos de trabajo de eventos o Event Workflow
- Orquestador
Por mencionar algunos. Estos patrones pueden volverse bastante complejos de escalar. La sincronización entre eventos, así como la comunicación entre procesos empieza a volverse todo un reto en soluciones que manejan cientos o miles de usuarios. Sin mencionar los retos de desarrollo o mantemiento de infraestructura. Algunas características que pudieran considerarse limitaciones de arquitecturas serverless, dentro de ciertos escenarios son:
- No hay un manejo del estado del proceso (stateless).
- La persistencia de los procesos es de una corta duración (ephemeral).
¿Qué es Azure Durable Functions?
Es un servicio dentro de la categoría PaaS en Azure, una extensión de Azure Functions y finalmente, se describe como la evolución del Durable Task Framework que pertenece además a la categoría de código abierto.
Algo que lo hace un diferenciador, es que Azure Durable Functions permite implementar flujos de trabajo que pueden mantener un estado que es durable, de ahí su nombre de Durable Functions.
¿Cuáles son las ventajas?
- Los flujos de trabajo son implementados con código, lo cual la hace una herramienta pensada en programadores.
- Puede utilizarse el patrón de event sourcing en el que es posible guardar el estado de la función, es decir es una solución stateful y donde el estado es manejado por la plataforma.
- Se pueden llamar a otras funciones de forma síncrona o asíncrona e interactuar con el resultado de estas.
- Es posible escalar las funciones en base a la demanda del cliente, como cualquier servicio serverless.
Hasta ahora hemos descrito en general el servicio de Durable Functions, veamos los componentes de una solución con este servicio:
Existen 4 tipos de funciones:
- Cliente: Son el punto de entrada en la creación de una orquestación de Durable Functions. Son las funciones que se ejecutan en respuesta a un evento. Ejemplos de ellos son: un request de HTTP, un nuevo mensaje en un queue, o un nuevo evento. Se pueden escribir en cualquier lenguaje soportado en Azure Functions.
- Orquestador: Es aquella función que describe el orden en que se ejecutarán las funciones que forman parte de la solución. Se escriben en C# or Javascript.
- De actividad: Son las unidades básicas de trabajo en una orquestación de Durable Function. Una actividad contiene en sí la tarea que se ejecutará dentro de la orquestación.
- De entidad: Este tipo de funciones es opcional dentro de un flujo de trabajo, ya que son un tipo especial de funciones. Sirven para leer o modificar algunas partes de un estado. Estas entidades guardan información del estado y se denominan Durable Entities o entidades durables. Las funciones de entidad no tienen una definición específica de código y manejan el estado de manera explícita. (aquí más información)
¿Cuáles son los escenarios en los que se pueden usar los Durable Functions?
Existen muchos patrones de flujos de trabajo donde se puede hacer uso de las ventajas que ofrece el servicio de Azure Durable Functions. Ejemplos de ellos son:
- Funciones en cadena o Function chaining.
- Funciones ejecutadas en paralelo.
- Funciones ejecutadas de manera asíncrona (con un endpoint para enviar el estado actual de la tarea que se está ejecutando).
- Monitor: Similar al anterior pero en este caso hablamos de un proceso que es recurrente, por ejemplo un proceso en espera de que ciertas condiciones se cumplan para ejecutar otro proceso.
- Interacción humana: Procesos en donde es necesario un proceso manual dentro de un proceso automatizado.
Los lenguajes de programacion en los que esta disponible Azure Durable Functions son C#, y C# script. JavaScript, Python (en Public Preview), F# y PowerShell.
Observaciones importantes
Existen algunas restricciones para la función orquestador dentro de una aplicación de Azure Durable Functions:
- La función de orquestador debe ser determinista.
- El código de la función no debe bloquear el flujo de ejecución.
- No debe iniciar operaciones async, excepto la API de DurableOrchestrationContext.
- No tener loops infinitos.
- Utilizar TraceWriter para el logging.
Recordemos que esta función es la que controlará en qué momento se ejecutan las demás funciones que son parte del flujo de trabajo, por lo que se ejecutará las veces que sean necesarias hasta terminarlo. Más acerca de esto en la documentación oficial: https://bit.ly/orchestrator-rules
Finalmente, un ejemplo de un Hello World para Azure Durable Functions utilizando c# que puedes descargar y ejecutarlo para explorar las funcionalidades de una aplicación utilizando ejecución de funciones en cadena. Los prerrequisitos para ejecutarlo localmente son:
- Visual Studio Code
- Extension de Azure Functions
- Cuenta en Azure (puedes obtenerla gratuitamente).
- Emulador local para Azure Storage (sólo en Windows) o una cuenta de Azure Storage.
- SDK de .net core 3.1 o la más reciente
El video de la charla de éste tema y la explicación de la aplicación se puede ver en el siguiente link.
Conclusión
Después de haber experimentado apenas con las funcionalidades básicas de este servicio, me ha parecido un excelente servicio para la implementación de flujos de trabajos más complejos y/o donde es necesario guardar información de estado, incluso también manejado por la plataforma. Los escenarios en donde pueden utilizarse son muchísimos, además que es un servicio frecuentemente con funcionalidades nuevas. En la última versión es posible utilizar un proveedor de almacenamiento de estado diferente a Azure Table Storage, lo cual lo hace aun más personalizable y escalable con bases de datos como MS SQL Server, PostgresSql, o CosmosDB.
Recursos para aprender más
Herramienta para monitoreo de Azure Durable Functions.
Ejemplo de cómo implementar el patron de Circuit Break con Durable Functions por Jeff Hollan
Documentación Oficial de Microsoft Azure Durable Functions en español
Gracias por leerme!
Happy coding!