Encadenamiento de funciones en Durable Functions: Hello Sequence de ejemplo

El encadenamiento de funciones hace referencia al patrón de ejecución de una secuencia de funciones en un orden concreto. A menudo la salida de una función tiene que aplicarse a la entrada de otra función. En este artículo se describe la secuencia de encadenamiento que se crea al completar el inicio rápido de Durable Functions (C#, JavaScript, Python, PowerShell, o Java). Para más información sobre Durable Functions, consulte Durable Functions overview (Información general de Durable Functions).

Prerequisites

Funciones

En este artículo se explican las funciones siguientes en la aplicación de ejemplo:

  • E1_HelloSequence: una función de orquestador que llama a E1_SayHello varias veces en una secuencia. Almacena las salidas de las llamadas de E1_SayHello y registra los resultados.
  • E1_SayHello: una función de actividad que antepone una cadena con "Hello".
  • HttpStart: función de cliente de larga duración desencadenada por HTTP que inicia una instancia del orquestador.

Función de orquestador E1_HelloSequence

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

Todas las funciones de orquestación de C# deben tener un parámetro de tipo DurableOrchestrationContext, que existe en el ensamblado Microsoft.Azure.WebJobs.Extensions.DurableTask. Este objeto de contexto le permite llamar a otras funciones de actividad y pasar parámetros de entrada con su método CallActivityAsync.

El código llama a E1_SayHello tres veces en secuencia con distintos valores de parámetro. El valor devuelto de cada llamada se agrega a la lista outputs, que se devuelve al final de la función.

Función de actividad E1_SayHello

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
    string name = context.GetInput<string>();
    return $"Hello {name}!";
}

Las actividades usan el atributo ActivityTrigger. Use el IDurableActivityContext proporcionado para realizar acciones relacionadas con la actividad, como el acceso al valor de entrada mediante GetInput<T>.

La implementación de E1_SayHello es una operación de formato de cadena relativamente sencilla.

En lugar de enlazar a un IDurableActivityContext, puede enlazar directamente con el tipo que se pasa a la función de actividad. Por ejemplo:

[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

Función de cliente HttpStart

Puede iniciar una instancia de la función de orquestador mediante una función de cliente. Usará la función desencadenada por HTTP HttpStartpara iniciar instancias de E1_HelloSequence.

public static class HttpStart
{
    [FunctionName("HttpStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
        [DurableClient] IDurableClient starter,
        string functionName,
        ILogger log)
    {
        // Function input comes from the request content.
        object eventData = await req.Content.ReadAsAsync<object>();
        string instanceId = await starter.StartNewAsync(functionName, eventData);

        log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}

Para interactuar con los orquestadores, la función tiene que incluir un enlace de entrada DurableClient. El cliente se utiliza para iniciar una orquestación. También puede ayudarle a devolver una respuesta HTTP que contiene las direcciones URL para comprobar el estado de la nueva orquestación.

Ejecución del ejemplo

Para ejecutar la orquestación de E1_HelloSequence, envíe la siguiente solicitud POST HTTP a la función HttpStart.

POST http://{host}/orchestrators/E1_HelloSequence

Nota

El fragmento de código HTTP anterior da por supuesto que hay una entrada en el archivo host.json que elimina el prefijo api/ predeterminado de todas las direcciones URL de las funciones de activación de HTTP. Puede encontrar el marcador para esta configuración en el archivo host.json en los ejemplos.

Por ejemplo, si ejecuta el ejemplo en una aplicación de función llamada "myfunctionapp", reemplace "{host}" por "myfunctionapp.azurewebsites.net".

El resultado es una respuesta HTTP 202, similar a la siguiente (acortada para simplificar):

HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

(...trimmed...)

En este punto, la orquestación se pone en cola y comienza a ejecutarse inmediatamente. La dirección URL en el encabezado Location puede usarse para comprobar el estado de la ejecución.

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

El resultado es el estado de la orquestación. Se ejecuta y se completa con rapidez, por lo que se muestra con el estado Completed (Completado) con una respuesta similar a la siguiente (acortada para simplificar):

HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8

{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}

Como puede ver, el valor de runtimeStatus de la instancia es Completed (Completado) y output contiene el resultado serializado con JSON de la ejecución de la función de orquestador.

Nota

Puede implementar una lógica de inicio similar para otros tipos de desencadenadores, como queueTrigger, eventHubTrigger o timerTrigger.

Observe los registros de ejecución de la función. La función E1_HelloSequence se ha iniciado y completado varias veces debido al comportamiento de reproducción descrito en el tema sobre la confiabilidad de la orquestación. Por otro lado, solo ha habido tres de ejecuciones de E1_SayHello, puesto que esas ejecuciones de función no se reproducen.

Pasos siguientes

En este ejemplo se ha demostrado una orquestación de encadenamiento de función simple. En el ejemplo siguiente se muestra cómo implementar el de distribución ramificada de salida y entrada.