En los artículos anteriores de esta serie se explicó que era la tecnología Serverless y las características principales de Azure Functions. En éste vamos a hablar de Workflows y Azure Durable Functions.
En su definición más simple podríamos decir que un workflow es básicamente un flujo de trabajo, consistente en un conjunto de actividades o tareas relacionadas siguiendo una determinada lógica con el objetivo de ejecutar de forma ordenada trabajos, procesos o servicios normalmente repetitivos. La ejecución de una tarea depende del resultado de tareas anteriores o en general del estado del workflow.
Como ejemplos, existen multitud en nuestro día a día tales como peticiones de servicios a nuestro Help-Desk (Onboarding, incidencias), compra de tickets, procesado de pedidos, procesado de facturas, validación y envío de ficheros a terceros, etc.
Azure Durable Functions es un servicio Serverless ofrecido por Microsoft como una extensión de Azure Functions, que permite la implementación de workflows con soporte para almacenarinformación de estado, normalmente empleadas en la automatización de procesos complejos y/o de larga duración. Por tanto, dispondremos de un servicio, por defecto usando Azure Storage, para almacenar la información de estado. Podríamos definir este framework del siguiente modo:
Tabla de almacenamiento de instancias de workflows.
Tabla de histórico de acciones y tareas realizadas.
[FunctionName("HelloOrquestrator")]
public static string Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
string name = context.GetInput();
// Código del orquestador
string message = await context.CallActivityAsync("HelloActivity", name)
return $"Hello {name}from orquestrator!";
}
- Consultar el estado del workflow
- Finalizar el workflow
- Enviar eventos mientras el workflow está en ejecución
- Eliminar la información de la tabla de históricos en Azure Storage
[FunctionName("InitWorkflow")]
public static Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, “get”, "post")] HttpRequestMessage request,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
string name = context.GetInput();
return $"Hello {name} from activity function!";
}
[FunctionName("HelloActivity")]
public static string Hello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name} from activity function!";
}
Además de llamar a funciones de actividad, los orquestadores pueden llamar a otros orquestadores más pequeños a modo de componentes reutilizables. Por ejemplo, podemos crear un workflow más complejo a partir de una biblioteca de funciones de orquestador más pequeñas y modulares.
Las funciones de entidad definen operaciones para leer y actualizar pequeñas partes de estado, conocidas como entidades duraderas o con estado. Permiten distribuir la información de estado del workflow más allá del Workflow Custom Status asociado a la función de orquestación.
Una vez vistos los tipos de funciones se podría ampliar la definición de Azure Durable Functions como:
Las funciones de actividad son llamadas en forma secuencial desde el orquestador y cada una puede recibir como entrada la salida de la ejecución de la función anterior.
Fan-out / fan-in se refiere al patrón de arquitectura consistente en ejecutar múltiples funciones al mismo tiempo en paralelo y luego realizar algún tipo de agregación o consolidación de los resultados para entregarlo a la siguiente tarea en el flujo de trabajo del workflow.
Las Durable Functions exponen métodos API REST no sólo para iniciar instancias de orquestación sino para interactuar con el orquestador una vez iniciado:
El patrón de arquitectura Monitor se refiere a un proceso recurrente en un flujo de trabajo, por ejemplo, sondeo o polling hasta que se cumplen determinadas condiciones en sistemas externos o incluso dentro del propio workflow. Por ejemplo, el sondeo del propio estado del workflow con posterior envío de información al interfaz de usuario vía Signar-R o publicación de actualizaciones de estado vía Azure Service Bus o Event Hubs.
Siempre que una persona real esté involucrada en un workflow para supervisar, aprobar o ejecutar cualquier otra acción, el proceso debe poder enviar notificaciones a dicha persona y recibir respuestas de forma asíncrona. Es aquí donde cobran especial importancia las funciones Timers y la recepción de eventos externos como elementos decisorios a la hora de finalizar funciones debido a tiempos de timeout excedidos.
Los modelos de facturación son básicamente los mismos que los ya descritos para Azure Functions en anteriores artículos.
No obstante, habría que añadir el coste derivado de la existencia de Azure Storage como medio de almacenamiento del estado. Este coste suele ser pequeño. Aun así, recomiendo eliminar la información almacenada de forma periódica para todos aquellos workflows obsoletos cuya información de estado no tiene sentido almacenarla.
En la actualidad los lenguajes soportados por el Framework son C#, JavaScript, Python, F# y PowerShell. En este artículo usaré C# en los ejemplos incluidos.
En los siguientes artículos de esta serie se mostrarán conceptos avanzados y un escenario práctico que, sin duda, ayudará a entender mejor todo lo explicado anteriormente.
Autor del artículo
José Antonio Muro