Partilhar via


Encadeamento de funções

Encadeamento de funções é um padrão em que executas uma sequência de funções por ordem. É comum passar a saída de uma função para a entrada da seguinte. Este artigo descreve a sequência de encadeamento que constróis quando completas o quickstart Durable Functions (C#, JavaScript, TypeScript, Python, PowerShell ou Java). Saiba mais na visão geral de Durable Functions.

Pré-requisitos

Encadeamento de funções é um padrão em que executas uma sequência de atividades por ordem. É comum passar a saída de uma atividade para a entrada da seguinte. Este artigo descreve a sequência de encadeamento dos SDKs de Tarefas Duráveis para .NET, JavaScript, Python e Java.

Funções

Este artigo descreve estas funções na aplicação de exemplo:

  • E1_HelloSequence: Uma função orquestradora que chama E1_SayHello várias vezes em sequência. Armazena cada saída e regista os resultados.
  • E1_SayHello: Uma função de atividade que adiciona "Olá" ao início de uma cadeia.
  • HttpStart: Uma função cliente durável ativada por HTTP que inicia uma instância do orquestrador.

Este artigo descreve estes componentes na aplicação de exemplo:

  • GreetingOrchestration, greetingOrchestrator, function_chaining_orchestrator, ou ActivityChaining: Um orquestrador que chama múltiplas atividades em sequência. Armazena cada saída e regista os resultados.
  • Funções de atividade: Atividades que processam a entrada e devolvem resultados. Cada atividade realiza uma transformação simples na entrada.
  • Cliente: Uma aplicação cliente que inicia uma instância do orquestrador e espera pelo resultado.

Orchestrator

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

O código chama E1_SayHello três vezes em sequência com diferentes valores de parâmetro. O valor de retorno de cada chamada é adicionado à outputs lista, que é retornada no final da função.

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

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 .NET orquestradores herdam de TaskOrchestrator<TInput, TOutput>. O TaskOrchestrationContext permite-lhe chamar atividades usando CallActivityAsync. O código chama três atividades em sequência, onde cada atividade recebe o resultado da atividade anterior.

Activity

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

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

E1_SayHello Formata uma cadeia de cumprimentos.

Em vez de ligar a IDurableActivityContext, liga diretamente ao tipo passado na função de atividade. Por exemplo:

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

As atividades no SDK de Tarefas Duradouras herdam de TaskActivity<TInput, TOutput>:

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!");
    }
}

Para obter serviços como ILogger, utilize a injeção de dependência. Adicione o [DurableTask] atributo para registar a atividade junto do trabalhador.

Client

Inicia uma instância de função de orquestrador a partir de uma função cliente. Use a função ativada por HTTP HttpStart 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 ligação de entrada. Use o cliente para iniciar uma orquestração e retorne uma resposta HTTP que inclua URLs para verificar o estado da nova orquestração.

Inicia uma orquestração a partir de uma aplicação cliente. O cliente agenda a orquestração e pode esperar pela conclusão.

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 ligação com o Durable Task Scheduler. Use ScheduleNewOrchestrationInstanceAsync para iniciar uma orquestração e WaitForInstanceCompletionAsync esperar pela conclusão.

Executar o exemplo

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

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

Nota

O trecho HTTP anterior assume que o ficheiro host.json do exemplo remove o prefixo padrão api/ de todas as URLs das funções de disparo HTTP. Encontre esta configuração no ficheirohost.json do exemplo.

Por exemplo, se estiver a executar a amostra numa aplicação de função chamada myfunctionapp, substitua {host} por myfunctionapp.azurewebsites.net.

O pedido devolve HTTP 202 (cortado para 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 entra em fila e começa a correr imediatamente. Use o URL no Location cabeçalho para verificar o estado da execução.

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

A resposta mostra o estado da orquestração. Como termina rapidamente, a instância está frequentemente no estado Concluído e retorna uma resposta como esta (cortada para 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 está Concluída e output contém o resultado serializado em JSON da execução da função do orquestrador.

Nota

Implemente lógica inicial semelhante para outros tipos de gatilhos, como queueTrigger, eventHubTrigger, ou timerTrigger.

Revise os registos de execução da função. A função E1_HelloSequence inicia e completa várias vezes devido ao comportamento de repetição descrito na fiabilidade da orquestração. Mas E1_SayHello só executa três vezes porque as execuções de funções de atividade não se repetem.

Para analisar a amostra, precisa de:

  1. Inicie o emulador Durable Task Scheduler (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 worker para registar o orquestrador e as atividades.

  3. Executa o cliente para agendar uma orquestração e espera pelo resultado.

A saída do cliente mostra o resultado da orquestração encadeada:

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

Os registos de trabalho mostram que cada atividade é executada em sequência e transmite a sua saída para a atividade seguinte.

Próximos passos

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

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

Para exemplos completos de SDK JavaScript, consulte os exemplos de SDK JavaScript para Tarefas Duradouras.