Encadeamento de funções em funções duráveis - Exemplo de sequência Hello
Artigo
Encadeamento de funções refere-se ao padrão de execução de uma sequência de funções em uma ordem específica. Muitas vezes, a saída de uma função precisa ser aplicada à entrada de outra função. Este artigo descreve a sequência de encadeamento que você cria ao concluir o início rápido do Durable Functions (C#, JavaScript, TypeScript, Python, PowerShell ou Java). Para obter mais informações sobre funções duráveis, consulte Visão geral de funções duráveis.
A versão 4 do modelo de programação Node.js para o Azure Functions está disponível em geral. O novo modelo v4 foi projetado para ter uma experiência mais flexível e intuitiva para desenvolvedores de JavaScript e TypeScript. Saiba mais sobre as diferenças entre v3 e v4 no guia de migração.
Nos trechos de código a seguir, JavaScript (PM4) indica o modelo de programação V4, a nova experiência.
As funções
Este artigo explica as seguintes funções no aplicativo de exemplo:
E1_HelloSequence: Uma função de orquestrador que chama E1_SayHello várias vezes em uma sequência. Ele armazena as saídas das E1_SayHello chamadas e registra os resultados.
E1_SayHello: Uma função de atividade que precede uma cadeia de caracteres com "Olá".
HttpStart: Uma função de cliente durável acionada por HTTP que inicia uma instância do orquestrador.
Todas as funções de orquestração C# devem ter um parâmetro do tipo DurableOrchestrationContext, que existe no Microsoft.Azure.WebJobs.Extensions.DurableTask assembly. 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.
function.json
Se você usar o Visual Studio Code ou o portal do Azure para desenvolvimento, aqui está o conteúdo do arquivo de function.json para a função orchestrator. A maioria dos arquivos function.json orquestrador se parece quase exatamente com isso.
O importante é o orchestrationTrigger tipo de ligação. Todas as funções do orquestrador devem usar esse tipo de gatilho.
Aviso
Para cumprir a regra "sem E/S" das funções do orquestrador, não use nenhuma ligação de entrada ou saída ao usar a orchestrationTrigger ligação de gatilho. Se outras ligações de entrada ou saída forem necessárias, elas devem ser usadas no contexto de activityTrigger funções, que são chamadas pelo orquestrador. Para obter mais informações, consulte o artigo sobre restrições de código de função do orchestrator.
Todas as funções de orquestração JavaScript devem incluir o durable-functions módulo. É uma biblioteca que permite escrever funções duráveis em JavaScript. Há três diferenças significativas entre uma função orchestrator e outras funções JavaScript:
A função é envolvida em uma chamada para o durable-functions método do orchestrator módulo (aqui df).
A função deve ser síncrona. Como o método 'orchestrator' lida com a chamada final para 'context.done', a função deve simplesmente 'retornar'.
O context objeto contém um df objeto de contexto de orquestração durável que permite chamar outras funções de atividade e passar parâmetros de entrada usando seu callActivity método. O código chama E1_SayHello três vezes em sequência com diferentes valores de parâmetro, usando yield para indicar que a execução deve aguardar as chamadas de função de atividade assíncrona para ser retornado. O valor de retorno de cada chamada é adicionado à outputs matriz, que é retornada no final da função.
Todas as funções de orquestração JavaScript devem incluir o durable-functions módulo. Este módulo permite que você escreva funções duráveis em JavaScript. Para usar o modelo de programação de nó V4, você precisa instalar a versão de visualização v3.x do durable-functions.
Há duas diferenças significativas entre uma função orchestrator e outras funções JavaScript:
A função deve ser síncrona. A função deve simplesmente "retornar".
O context objeto contém um df objeto de contexto de orquestração durável que permite chamar outras funções de atividade e passar parâmetros de entrada usando seu callActivity método. O código chama sayHello três vezes em sequência com diferentes valores de parâmetro, usando yield para indicar que a execução deve aguardar as chamadas de função de atividade assíncrona para ser retornado. O valor de retorno de cada chamada é adicionado à outputs matriz, que é retornada no final da função.
Nota
Python Durable Functions estão disponíveis apenas para o tempo de execução do Functions 3.0.
function.json
Se você usar o Visual Studio Code ou o portal do Azure para desenvolvimento, aqui está o conteúdo do arquivo de function.json para a função orchestrator. A maioria dos arquivos function.json orquestrador se parece quase exatamente com isso.
O importante é o orchestrationTrigger tipo de ligação. Todas as funções do orquestrador devem usar esse tipo de gatilho.
Aviso
Para cumprir a regra "sem E/S" das funções do orquestrador, não use nenhuma ligação de entrada ou saída ao usar a orchestrationTrigger ligação de gatilho. Se outras ligações de entrada ou saída forem necessárias, elas devem ser usadas no contexto de activityTrigger funções, que são chamadas pelo orquestrador. Para obter mais informações, consulte o artigo sobre restrições de código de função do orchestrator.
Todas as funções de orquestração Python devem incluir o durable-functions pacote. É uma biblioteca que permite escrever funções duráveis em Python. Existem duas diferenças significativas entre uma função orchestrator e outras funções Python:
O arquivo deve registrar a função do orquestrador como um orquestrador, indicando main = df.Orchestrator.create(<orchestrator function name>) no final do arquivo. Isso ajuda a distingui-lo de outras funções auxiliares declaradas no arquivo.
O context objeto permite chamar outras funções de atividade e passar parâmetros de entrada usando seu call_activity método. O código chama E1_SayHello três vezes em sequência com diferentes valores de parâmetro, usando yield para indicar que a execução deve aguardar as chamadas de função de atividade assíncrona para ser retornado. O valor de retorno de cada chamada é retornado no final da função.
[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 o fornecido IDurableActivityContext para executar ações relacionadas à atividade, como acessar o valor de entrada usando GetInput<T>.
A implementação de é uma operação de formatação de cadeia de E1_SayHello caracteres relativamente trivial.
Em vez de vincular a um IDurableActivityContext, você pode vincular diretamente ao tipo que é passado para a função de atividade. Por exemplo:
O arquivo de function.json para a função E1_SayHello de atividade é semelhante ao de exceto que ele usa um activityTrigger tipo de ligação em vez de um orchestrationTrigger tipo de E1_HelloSequence ligação.
Todas as funções de atividade chamadas por uma função de orquestração devem usar a activityTrigger ligação.
A implementação de é uma operação de formatação de cadeia de E1_SayHello caracteres relativamente trivial.
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
Ao contrário da função de orquestração, uma função de atividade não precisa de configuração especial. A entrada passada para ele pela função orchestrator está localizada no context.bindings objeto sob o nome da activityTrigger ligação - neste caso, context.bindings.name. O nome da associação pode ser definido como um parâmetro da função exportada e acessado diretamente, que é o que o código de exemplo faz.
A implementação de é uma operação de formatação de cadeia de sayHello caracteres relativamente trivial.
Ao contrário da função de orquestração, uma função de atividade não precisa de configuração especial. A entrada passada para ele pela função orquestrador é o primeiro argumento para a função. O segundo argumento é o contexto de invocação, que não é usado neste exemplo.
E1_SayHello/function.json
O arquivo de function.json para a função E1_SayHello de atividade é semelhante ao de exceto que ele usa um activityTrigger tipo de ligação em vez de um orchestrationTrigger tipo de E1_HelloSequence ligação.
Ao contrário da função orquestradora, uma função de atividade não precisa de configuração especial. A entrada passada para ele pela função orchestrator é diretamente acessível como o parâmetro para a função.
Função de cliente HttpStart
Você pode iniciar uma instância da função orchestrator usando uma função de cliente. Você usará a função acionada HttpStart HTTP para iniciar instâncias do 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, a função deve incluir uma DurableClient ligação de entrada. Você usa o cliente para iniciar uma orquestração. Ele também pode ajudá-lo a retornar uma resposta HTTP contendo URLs para verificar o status da nova orquestração.
Use df.getClient para obter um DurableOrchestrationClient objeto. Você usa o cliente para iniciar uma orquestração. Ele também pode ajudá-lo a retornar uma resposta HTTP contendo URLs para verificar o status da nova orquestração.
Para gerenciar e interagir com orquestradores, a função precisa de uma durableClient ligação de entrada. Essa ligação precisa ser especificada no extraInputs argumento ao registrar a função. Uma durableClient entrada pode ser obtida ligando para df.input.durableClient().
Use df.getClient para obter um DurableClient objeto. Você usa o cliente para iniciar uma orquestração. Ele também pode ajudá-lo a retornar uma resposta HTTP contendo URLs para verificar o status da nova orquestração.
Para interagir com orquestradores, a função deve incluir uma durableClient ligação de entrada.
HttpStart/__init__.py
import logging
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instance_id = await client.start_new(req.route_params["functionName"], None, None)
logging.info(f"Started orchestration with ID = '{instance_id}'.")
return client.create_check_status_response(req, instance_id)
Use o DurableOrchestrationClient construtor para obter um cliente Durable Functions. Você usa o cliente para iniciar uma orquestração. Ele também pode ajudá-lo a retornar uma resposta HTTP contendo URLs para verificar o status da nova orquestração.
Executar o exemplo
Para executar a E1_HelloSequence orquestração, envie a seguinte solicitação HTTP POST para a HttpStart função.
POST http://{host}/orchestrators/E1_HelloSequence
Nota
O trecho HTTP anterior pressupõe que há uma entrada no arquivo que remove o prefixo padrão api/ de todas as URLs de funções de gatilho host.json HTTP. Você pode encontrar a marcação para essa configuração no host.json arquivo nos exemplos.
Por exemplo, se você estiver executando o exemplo em um aplicativo de função chamado "myfunctionapp", substitua "{host}" por "myfunctionapp.azurewebsites.net".
O resultado é uma resposta HTTP 202, como esta (cortada para brevidade):
Neste ponto, a orquestração é enfileirada e começa a ser executada imediatamente. O URL no Location cabeçalho pode ser usado para verificar o status da execução.
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
O resultado é o status da orquestração. Ele é executado e concluído rapidamente, para que você o veja no estado Concluído com uma resposta semelhante a esta (cortada para brevidade):
Como você pode ver, o runtimeStatus da instância é Completed e contém output o resultado serializado em JSON da execução da função orchestrator.
Nota
Você pode implementar lógica inicial semelhante para outros tipos de gatilho, como queueTrigger, eventHubTriggerou timerTrigger.
Observe os logs de execução da função. A E1_HelloSequence função foi iniciada e concluída várias vezes devido ao comportamento de repetição descrito no tópico de confiabilidade da orquestração. Por outro lado, houve apenas três execuções de uma vez que essas execuções de E1_SayHello função não são repetidas.
Próximos passos
Este exemplo demonstrou uma orquestração simples de encadeamento de funções. O próximo exemplo mostra como implementar o padrão fan-out/fan-in.