Skip to main content

¿Qué son las Azure Durable Functions?

Introducción

 

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.

¿Qué es un Workflow?
 

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.

¿Qué son las Azure Durable Functions?
 

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:

Propiedades principales

  • En la ejecución de un workflow podremos usar la información de estado almacenada a partir de tareas anteriores para activar diferentes lógicas.
  • Definición de workflows en código. Permite una mayor flexibilización y capacidad de personalización.
  • Ejecución de workflows de larga duración. Por ejemplo, aquellos que esperan la interacción de terceros para validar solicitudes o procesos.
  • Fácil integración con otros servicios de Azure (Service Bus, Event Grid, Event Hub, Azure Storage, etc.).
  • Durable Functions es open-source, Microsoft acepta contribuciones y hoy en día la comunidad es bastante activa.
  • Las propiamente dichas de entornos Serverless.

Tipos de Azure Durable Functions

Orquestadores (Stateful)
 
  • Principal componente del framework por el cual adquiere la condición de Stateful para almacenar información de estado.
  • Define toda la lógica de ejecución, qué tareas o funciones de actividad, en qué orden, cómo y cuándo son ejecutadas.
  • Pueden llamar a funciones de actividad para ejecutar tareas, suborquestadores, activar timers o interactuar con funciones de entidad.
  • El código a ejecutar debe ser determinista. Para un mismo conjunto de parámetros de entrada, la salida debe ser siempre la misma. De lo contrario la ejecución del workflow generará excepciones.
  • No puede iniciar operaciones asíncronas de entrada / salida sin utilizar funciones de actividad o hacer uso de su objeto context.
  • Si el orquestador está pendiente de obtener un resultado de una función de actividad o a la espera de la conclusión de un timer, el coste no es cargado al cliente.
  • Permite añadir un estado personalizado (Workflow Custom Status) de hasta 16Kb que puede ser consultado mediante el uso de APIs proporcionadas por el propio framework. Muy útil en caso de necesitar mostrar información personalizada del estado del workflow en la interfaz de usuario.
  • El estado e histórico de acciones del workflow es almacenado por defecto en un conjunto de tablas incluidas en un Task Hub sobre Azure Storage:

Tabla de almacenamiento de instancias de workflows.

Tabla de histórico de acciones y tareas realizadas.

  • A nivel código una función de orquestación queda definida por el uso de un servicio o trigger binding de tipo OrchestrationTrigger:

[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!";

}

Funciones Cliente
 
  • Son las funciones utilizadas para iniciar los orquestadores.
  • También pueden interactuar con orquestadores una vez iniciados para:

- 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

  • Pueden interactuar con funciones de entidad.
  • Pueden iniciarse en respuesta a eventos emitidos desde múltiples fuentes como mensajes enviados a queues, peticiones HTTP, subida de ficheros en Azure Storage, etc.
  • A nivel código una función cliente queda definida por el uso de un trigger binding de tipo DurableClient. Este sería un ejemplo de una función cliente que inicia un workflow en respuesta a una petición HTTP:

[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!";

}

Funciones de Actividad
 
  • Constituyen cada una de las tareas en las que un workflow puede descomponerse.
  • Se pueden ejecutar en serie, en paralelo o combinaciones.
  • Son llamadas desde los orquestadores o suborquestadores.
  • Permiten realizar llamadas asíncronas a otros servicios de entrada o salida, al contrario que las funciones de orquestación en las cuales al ejecutarse en un único hilo (single-threading) no está permitido.
  • Pueden utilizar bindings de entrada y salida del mismo modo que Azure Functions para acceder a otros servicios (Storage AccountsService Bus, etc.).
  • La respuesta de este tipo de funciones es almacenada por los orquestadores a modo de información de estado. Por sí mismas no almacenan información de estado por lo que son consideradas como funciones Stateless.
  • A nivel código una función de actividad queda definida por el uso inyectado de un servicio trigger binding de tipo ActivityTrigger:

[FunctionName("HelloActivity")]

public static string Hello([ActivityTrigger] IDurableActivityContext context)

{

    string name = context.GetInput<string>();

    return $"Hello {name} from activity function!";

}

Suborquestadores
 

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.

Funciones de Entidad
 

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.

Timers
 
  • Son temporizadores a utilizar en funciones de orquestación para implementar delays o fijar timeouts en operaciones asíncronas de larga duración y/o que requieren interacción con servicios externos o personas.
  • Sustituyen a los métodos clásicos utilizados en los diferentes lenguajes para suspender la ejecución del hilo en ejecución, por ejemplo, métodos Thread.Sleep o Task.Delay en C#.

Una vez vistos los tipos de funciones se podría ampliar la definición de Azure Durable Functions como:

Tipos de Workflows

 

Function Chaining
 

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 out7Fan in
 

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.

Async HTTP APIs
 

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:

  • Consulta de Estado
  • Envío de Eventos
  • Finalización del Workflow
  • Borrado de datos de histórico
  • Interacción con funciones de estado
Monitor
 

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.

Human Interaction
 

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.

¿Es caro o barato el uso de Durable Functions?

 

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.

¿Qué lenguajes soportan actualmente?

 

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