Compartilhar via


Encadeamento de funções

O encadeamento de funções é um padrão em que você executa uma sequência de funções em ordem. É comum passar a saída de uma função para a entrada da próxima. Este artigo descreve a sequência de encadeamento que você cria ao concluir o início rápido Durable Functions (C#, JavaScriptTypeScript, Python, PowerShell ou Java). Saiba mais em Visão geral do Durable Functions.

Pré-requisitos

O encadeamento de funções é um padrão em que você executa uma sequência de atividades em ordem. É comum passar a saída de uma atividade para a entrada da próxima. Este artigo descreve a sequência de encadeamento dos SDKs de Tarefa Durável para .NET, JavaScript, Python e Java.

Functions

Este artigo descreve essas funções no aplicativo de exemplo:

  • E1_HelloSequence: uma função de orquestrador que chama E1_SayHello várias vezes na sequência. Ele armazena cada saída e registra os resultados.
  • E1_SayHello: uma função de atividade que adiciona "Hello" ao início de uma cadeia de caracteres.
  • HttpStart: função cliente durável acionada por HTTP que inicia uma instância do orquestrador.

Este artigo descreve esses componentes no aplicativo de exemplo:

  • GreetingOrchestration, greetingOrchestrator, function_chaining_orchestrator, ou ActivityChaining: um orquestrador que chama diversas atividades em sequência. Ele armazena cada saída e registra os resultados.
  • Funções de atividade: atividades que processam a entrada e retornam resultados. Cada atividade executa uma transformação simples na entrada.
  • Cliente: um aplicativo cliente que inicia uma instância do orquestrador e aguarda o resultado.

Orquestrador

[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 as funções de orquestração de C# devem ter um parâmetro do tipo DurableOrchestrationContext, que existe no assembly Microsoft.Azure.WebJobs.Extensions.DurableTask. Esse objeto de contexto permite chamar outras funções de atividade e passar parâmetros de entrada usando o método CallActivityAsync.

O código chama E1_SayHello três vezes seguidas com valores de parâmetros diferentes. O valor retornado de cada chamada é adicionado à lista outputs, que é retornada ao final da função.

Esse código mostra um orquestrador que chama três atividades em sequência e passa cada saída para a próxima atividade:

using System.Threading.Tasks;
using Microsoft.DurableTask;

[DurableTask]
public class GreetingOrchestration : TaskOrchestrator<string, string>
{
    public override async Task<string> RunAsync(TaskOrchestrationContext context, string name)
    {
        // Step 1: Say hello to the person
        string greeting = await context.CallActivityAsync<string>(nameof(SayHelloActivity), name);

        // Step 2: Process the greeting
        string processedGreeting = await context.CallActivityAsync<string>(nameof(ProcessGreetingActivity), greeting);

        // Step 3: Finalize the response
        string finalResponse = await context.CallActivityAsync<string>(nameof(FinalizeResponseActivity), processedGreeting);

        return finalResponse;
    }
}

Todos os orquestradores .NET herdam de TaskOrchestrator<TInput, TOutput>. O TaskOrchestrationContext permite que você chame atividades usando CallActivityAsync. O código chama três atividades em sequência, em que cada atividade recebe a saída da atividade anterior.

Atividade

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

As atividades usam o atributo ActivityTrigger. Use IDurableActivityContext para ações de atividade, como ler a entrada com GetInput<T>.

E1_SayHello formata uma cadeia de caracteres de saudação.

Em vez de associar a um IDurableActivityContext, associe diretamente ao tipo passado para a função de atividade. Por exemplo:

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

As atividades no SDK da Tarefa Durável herdam de TaskActivity<TInput, TOutput>:

using System.Threading.Tasks;
using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;

[DurableTask]
public class SayHelloActivity : TaskActivity<string, string>
{
    private readonly ILogger<SayHelloActivity> _logger;

    public SayHelloActivity(ILogger<SayHelloActivity> logger)
    {
        _logger = logger;
    }

    public override Task<string> RunAsync(TaskActivityContext context, string name)
    {
        _logger.LogInformation("Activity SayHello called with name: {Name}", name);
        return Task.FromResult($"Hello {name}!");
    }
}

[DurableTask]
public class ProcessGreetingActivity : TaskActivity<string, string>
{
    public override Task<string> RunAsync(TaskActivityContext context, string greeting)
    {
        return Task.FromResult($"{greeting} How are you today?");
    }
}

[DurableTask]
public class FinalizeResponseActivity : TaskActivity<string, string>
{
    public override Task<string> RunAsync(TaskActivityContext context, string response)
    {
        return Task.FromResult($"{response} I hope you're doing well!");
    }
}

Use a injeção de dependência para obter serviços como ILogger. Adicione o atributo [DurableTask] para registrar a atividade com o trabalhador.

Cliente

Inicie uma instância de função do orquestrador a partir de uma função cliente. Use a HttpStart função disparada por HTTP para iniciar instâncias 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 interagir com orquestradores, adicione uma DurableClient associação de entrada. Use o cliente para iniciar uma orquestração e retornar uma resposta HTTP que inclua URLs para verificar o status da nova orquestração.

Inicie uma orquestração a partir de um aplicativo cliente. O cliente agenda a orquestração e pode aguardar a conclusão.

using System;
using Microsoft.DurableTask.Client;

// Create the client
var client = DurableTaskClientBuilder.UseDurableTaskScheduler(connectionString).Build();

// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
    nameof(GreetingOrchestration),
    input: "World");

Console.WriteLine($"Started orchestration with ID: {instanceId}");

// Wait for the orchestration to complete
OrchestrationMetadata result = await client.WaitForInstanceCompletionAsync(
    instanceId,
    getInputsAndOutputs: true);

Console.WriteLine($"Orchestration completed with result: {result.ReadOutputAs<string>()}");

Crie o DurableTaskClient usando uma cadeia de conexão para o Agendador de Tarefas Duráveis. Use ScheduleNewOrchestrationInstanceAsync para iniciar uma orquestração e WaitForInstanceCompletionAsync aguardar a conclusão.

Execute o exemplo

Para executar a E1_HelloSequence orquestração, envie essa solicitação HTTP POST para a HttpStart função.

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

Observação

O snippet HTTP anterior pressupõe que o arquivo host.json do exemplo remove o prefixo padrão api/ de todas as URLs de função de gatilho HTTP. Localize essa configuração no arquivo dehost.json do exemplo.

Por exemplo, se você estiver executando o exemplo em um aplicativo de funções chamado myfunctionapp, substitua {host} por myfunctionapp.azurewebsites.net.

A solicitação retorna HTTP 202 (aparado para fins de brevidade):

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...)

A orquestração faz filas e começa a ser executada logo. Use a URL do Location cabeçalho para verificar o status da execução.

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

A resposta mostra o status da orquestração. Como ela é concluída rapidamente, a instância geralmente está no estado Concluído e retorna uma resposta como esta (cortada para fins de brevidade):

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"}

A instância runtimeStatus é Concluída e output contém o resultado serializado por JSON da execução da função do orquestrador.

Observação

Implementar lógica inicial semelhante para outros tipos de gatilho, como queueTrigger, eventHubTriggerou timerTrigger.

Examine os logs de execução de função. A E1_HelloSequence função é iniciada e concluída diversas vezes por causa do comportamento de reprodução descrito em confiabilidade da orquestração. Mas E1_SayHello é executado apenas três vezes porque as execuções das funções de atividade não são repetidas.

Para executar o exemplo, você precisa:

  1. Inicie o emulador do Agendador de Tarefas Duráveis (para desenvolvimento local):

    docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latest
    
  2. Inicie o trabalho para registrar o orquestrador e atividades.

  3. Execute o cliente para agendar uma orquestração e aguardar o resultado.

A saída do cliente exibe o resultado da orquestração em cadeia:

Started orchestration with ID: abc123
Orchestration completed with result: "Hello World! How are you today? I hope you're doing well!"

Os registros de trabalho mostram que cada atividade é executada em sequência e que sua saída é passada para a próxima atividade.

Próximas etapas

Este exemplo demonstra uma orquestração simples de encadeamento de funções. Em seguida, implemente o padrão fan-out/fan-in.

Este exemplo demonstra uma orquestração simples de encadeamento de funções. Em seguida, explore mais padrões.

Para obter exemplos completos do SDK do JavaScript, consulte os exemplos de SDK do JavaScript de Tarefa Durável.