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
Modelo de programação V3
Modelo de programação V4
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.
Modelo de programação V3
function.json
Se você desenvolver no Visual Studio Code ou no portal do Azure, aqui está o arquivo function.json do orquestrador.
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
],
"disabled": false
}
A configuração principal é orchestrationTrigger o tipo de associação. Todas as funções de orquestrador devem usar esse tipo de gatilho.
Aviso
Para seguir a regra "sem E/S" para funções de orquestrador, não use associações de entrada ou saída com a orchestrationTrigger associação de gatilho. Se você precisar de outras associações de entrada ou saída, use-as em activityTrigger funções que o orquestrador chama. Para obter mais informações, consulte restrições de código de função do orquestrador.
index.js
Aqui está a função orquestradora:
const df = require("durable-functions");
module.exports = df.orchestrator(function* (context) {
context.log("Starting chain sample");
const output = [];
output.push(yield context.df.callActivity("E1_SayHello", "Tokyo"));
output.push(yield context.df.callActivity("E1_SayHello", "Seattle"));
output.push(yield context.df.callActivity("E1_SayHello", "London"));
return output;
});
Todas as funções de orquestração de JavaScript devem incluir o módulo durable-functions. É uma biblioteca que permite que você escreva Durable Functions em JavaScript. Três diferenças importantes entre uma função de orquestrador e outras funções JavaScript:
- A função de orquestrador é uma função de gerador.
- A função é encapsulada em uma chamada para o método
durable-functions do módulo orchestrator (aqui df).
- A função é síncrona. Como o
orchestrator método chama context.done, a função retorna.
O objeto context contém um objeto de contexto de orquestração durável df que permite chamar outras funções de atividade e passa parâmetros de entrada usando o método callActivity. O código chama E1_SayHello três vezes em sequência com valores de parâmetros diferentes, usando yield para indicar que a execução deve aguardar as chamadas de função de atividade assíncrona serem retornadas. O valor retornado de cada chamada é adicionado à matriz outputs, que é retornada ao final da função.
Modelo de programação V4
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.orchestration("helloSequence", function* (context) {
context.log("Starting chain sample");
const output = [];
output.push(yield context.df.callActivity(helloActivityName, "Tokyo"));
output.push(yield context.df.callActivity(helloActivityName, "Seattle"));
output.push(yield context.df.callActivity(helloActivityName, "Cairo"));
return output;
});
Todas as funções de orquestração de JavaScript devem incluir o módulo durable-functions. Este módulo permite que você escreva Durable Functions em JavaScript. Para usar o nó de programação V4, você precisa instalar a v3.x versão do durable-functions.
Duas diferenças importantes entre uma função de orquestrador e outras funções JavaScript:
- A função de orquestrador é uma função de gerador.
- A função é síncrona. A função retorna.
O objeto context contém um objeto de contexto de orquestração durável df que permite chamar outras funções de atividade e passa parâmetros de entrada usando o método callActivity. O código chama sayHello três vezes em sequência com valores de parâmetros diferentes, usando yield para indicar que a execução deve aguardar as chamadas de função de atividade assíncrona serem retornadas. O valor retornado de cada chamada é adicionado à matriz outputs, que é retornada ao final da função.
Observação
Python Durable Functions estão disponíveis apenas para o runtime do Functions 3.0.
function.json
Se você usar Visual Studio Code ou o portal de Azure para desenvolvimento, veja o conteúdo do arquivo function.json para a função de orquestrador. A maioria dos arquivos function.json do orquestrador são quase exatamente iguais a esse.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
O importante é o tipo de vinculação de orchestrationTrigger. Todas as funções de orquestrador devem usar esse tipo de gatilho.
Aviso
Para obedecer a regra de "não fazer E/S" das funções de orquestrador, não use nenhuma associação de entrada ou saída ao usar a associação de gatilho orchestrationTrigger. Se outras associações de entrada ou de saída forem necessárias, elas deverão ser usadas no contexto das funções activityTrigger, que são chamadas pelo orquestrador. Para obter mais informações, confira o artigo Restrições de código na função de orquestrador.
__init__.py
Aqui está a função orquestradora:
import azure.functions as func
import azure.durable_functions as df
def orchestrator_function(context: df.DurableOrchestrationContext):
result1 = yield context.call_activity('E1_SayHello', "Tokyo")
result2 = yield context.call_activity('E1_SayHello', "Seattle")
result3 = yield context.call_activity('E1_SayHello', "London")
return [result1, result2, result3]
main = df.Orchestrator.create(orchestrator_function)
Todas as funções de orquestração Python devem incluir o pacote durable-functions. É uma biblioteca que permite que você escreva Durable Functions em Python. Duas diferenças importantes entre uma função de orquestrador e outras funções de Python:
- A função de orquestrador é uma função de gerador.
- O arquivo registra a função de orquestrador informando
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 objeto context permite chamar outras funções de atividade e passar parâmetros de entrada usando o método call_activity. O código chama E1_SayHello três vezes em sequência com valores de parâmetros diferentes, usando yield para indicar que a execução deve aguardar as chamadas de função de atividade assíncrona serem retornadas. O valor retornado de cada chamada é retornado no final da função.
O exemplo do PowerShell ainda não está disponível.
Java exemplo ainda não está disponível.
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.
O código a seguir mostra um orquestrador que chama três atividades em sequência:
import {
OrchestrationContext,
TOrchestrator,
} from "@microsoft/durabletask-js";
const greetingOrchestrator: TOrchestrator = async function* (
ctx: OrchestrationContext,
name: string
): any {
// Step 1: Say hello to the person
const greeting: string = yield ctx.callActivity(sayHello, name);
// Step 2: Process the greeting
const processedGreeting: string = yield ctx.callActivity(processGreeting, greeting);
// Step 3: Finalize the response
const finalResponse: string = yield ctx.callActivity(finalizeResponse, processedGreeting);
return finalResponse;
};
Todos os orquestradores JavaScript são funções de gerador (async function*) que usam yield para chamar atividades. O método callActivity do contexto de orquestração agenda a execução da atividade. O código chama três atividades em sequência, passando a saída de cada atividade para a próxima.
O código a seguir mostra um orquestrador que chama três atividades em sequência:
from durabletask import task
# Orchestrator function
def function_chaining_orchestrator(ctx: task.OrchestrationContext, name: str) -> str:
"""Orchestrator that demonstrates function chaining pattern."""
# Call first activity
greeting = yield ctx.call_activity(say_hello, input=name)
# Call second activity with the result from first activity
processed_greeting = yield ctx.call_activity(process_greeting, input=greeting)
# Call third activity with the result from second activity
final_response = yield ctx.call_activity(finalize_response, input=processed_greeting)
return final_response
Todos os orquestradores Python são funções geradoras que usam yield para chamar atividades. O método call_activity do contexto de orquestração agenda a execução da atividade. O código chama três atividades em sequência, passando a saída de cada atividade para a próxima.
Este exemplo é mostrado para .NET, JavaScript, Java e Python.
O código a seguir mostra um orquestrador que chama três atividades em sequência:
import com.microsoft.durabletask.DurableTaskGrpcWorker;
import com.microsoft.durabletask.DurableTaskSchedulerWorkerExtensions;
import com.microsoft.durabletask.TaskOrchestration;
import com.microsoft.durabletask.TaskOrchestrationFactory;
DurableTaskGrpcWorker worker = DurableTaskSchedulerWorkerExtensions.createWorkerBuilder(connectionString)
.addOrchestration(new TaskOrchestrationFactory() {
@Override
public String getName() { return "ActivityChaining"; }
@Override
public TaskOrchestration create() {
return ctx -> {
String input = ctx.getInput(String.class);
// Call activities in sequence, passing output from one to the next
String x = ctx.callActivity("Reverse", input, String.class).await();
String y = ctx.callActivity("Capitalize", x, String.class).await();
String z = ctx.callActivity("ReplaceWhitespace", y, String.class).await();
ctx.complete(z);
};
}
})
.build();
Em Java, os orquestradores são definidos usando TaskOrchestrationFactory. O método do contexto agenda a execução da callActivity atividade e await() aguarda o resultado. O código chama três atividades em sequência, passando a saída de cada atividade para a próxima.
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}!";
}
Modelo de programação V3
E1_SayHello/function.json
O arquivo function.json da função de atividade E1_SayHello é semelhante ao de E1_HelloSequence, exceto por usar um tipo de associação activityTrigger em vez de um tipo de associação orchestrationTrigger.
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
],
"disabled": false
}
Observação
Use a activityTrigger associação para todas as funções de atividade que são chamadas por uma função de orquestração.
A implementação de E1_SayHello é uma operação de formatação de cadeia de caracteres relativamente simples.
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. O orquestrador passa a entrada no context.bindings objeto com o nome da activityTrigger associação, nesse caso, context.bindings.name. Defina o nome da associação como um parâmetro da função exportada para acessá-lo diretamente, como o exemplo faz.
Modelo de programação V4
sayHello formata uma cadeia de caracteres de saudação.
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.activity(helloActivityName, {
handler: function (input) {
return `Hello ${input}`;
},
});
Ao contrário da função de orquestração, uma função de atividade não precisa de configuração especial. O orquestrador passa a entrada como primeiro argumento para a função. O segundo argumento é o contexto de invocação, que este exemplo não usa.
E1_SayHello/function.json
O arquivo function.json da função de atividade E1_SayHello é semelhante ao de E1_HelloSequence, exceto por usar um tipo de associação activityTrigger em vez de um tipo de associação orchestrationTrigger.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
]
}
Observação
Todas as funções de atividade chamadas por uma função de orquestração devem usar a associação activityTrigger.
A implementação de E1_SayHello é uma operação de formatação de cadeia de caracteres relativamente simples.
E1_SayHello/__init__.py
def main(name: str) -> str:
return f"Hello {name}!"
Ao contrário de uma função orquestradora, uma função de atividade não requer configuração especial. A entrada passada para ela pela função de orquestrador é diretamente acessível como o parâmetro para a função.
Exemplo do PowerShell em breve.
Exemplo de Java em breve.
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.
As atividades no SDK da Tarefa Durável são funções simples:
import { ActivityContext } from "@microsoft/durabletask-js";
const sayHello = async (_ctx: ActivityContext, name: string): Promise<string> => {
return `Hello ${name}!`;
};
const processGreeting = async (_ctx: ActivityContext, greeting: string): Promise<string> => {
return `${greeting} How are you today?`;
};
const finalizeResponse = async (_ctx: ActivityContext, response: string): Promise<string> => {
return `${response} I hope you're doing well!`;
};
Ao contrário dos orquestradores, as atividades podem executar operações de E/S, como chamadas HTTP, consultas de banco de dados e acesso a arquivos. A entrada é passada diretamente como um parâmetro.
As atividades no SDK da Tarefa Durável são funções simples:
from durabletask import task
def say_hello(ctx: task.ActivityContext, name: str) -> str:
"""First activity that greets the user."""
return f"Hello {name}!"
def process_greeting(ctx: task.ActivityContext, greeting: str) -> str:
"""Second activity that processes the greeting."""
return f"{greeting} How are you today?"
def finalize_response(ctx: task.ActivityContext, response: str) -> str:
"""Third activity that finalizes the response."""
return f"{response} I hope you're doing well!"
Ao contrário dos orquestradores, as atividades podem executar operações de E/S, como chamadas HTTP, consultas de banco de dados e acesso a arquivos. A entrada é passada diretamente como um parâmetro.
Este exemplo é mostrado para .NET, JavaScript, Java e Python.
As atividades em Java são definidas usando TaskActivityFactory:
import com.microsoft.durabletask.TaskActivity;
import com.microsoft.durabletask.TaskActivityFactory;
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "Reverse"; }
@Override
public TaskActivity create() {
return ctx -> {
String input = ctx.getInput(String.class);
StringBuilder builder = new StringBuilder(input);
builder.reverse();
return builder.toString();
};
}
})
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "Capitalize"; }
@Override
public TaskActivity create() {
return ctx -> ctx.getInput(String.class).toUpperCase();
}
})
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "ReplaceWhitespace"; }
@Override
public TaskActivity create() {
return ctx -> {
String input = ctx.getInput(String.class);
return input.trim().replaceAll("\\s", "-");
};
}
})
Registre cada atividade com o construtor de trabalho usando addActivity. As atividades podem executar operações de E/S e retornar resultados ao orquestrador.
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.
Modelo de programação V3
HttpStart/function.json
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": ["post"]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "orchestrationClient",
"direction": "in"
}
],
"disabled": false
}
Para interagir com orquestradores, adicione uma durableClient associação de entrada.
HttpStart/index.js
const df = require("durable-functions");
module.exports = async function (context, req) {
const client = df.getClient(context);
const instanceId = await client.startNew(req.params.functionName, undefined, req.body);
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(context.bindingData.req, instanceId);
};
Use df.getClient para obter um DurableOrchestrationClient objeto. Use o cliente para iniciar uma orquestração e retornar uma resposta HTTP que inclua URLs para verificar o status da nova orquestração.
Modelo de programação V4
const df = require("durable-functions");
const { app } = require("@azure/functions");
app.http("httpStart", {
route: "orchestrators/{orchestratorName}",
extraInputs: [df.input.durableClient()],
handler: async (request, context) => {
const client = df.getClient(context);
const body = await request.json();
const instanceId = await client.startNew(request.params.orchestratorName, { input: body });
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(request, instanceId);
},
});
Para gerenciar e interagir com orquestradores, adicione uma durableClient associação de entrada. Especifique a associação no extraInputs argumento quando você registrar a função. Obtenha a durableClient entrada chamando df.input.durableClient().
Use df.getClient para obter um DurableClient objeto. Use o cliente para iniciar uma orquestração e retornar uma resposta HTTP que inclua URLs para verificar o status da nova orquestração.
HttpStart/function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": [
"post",
"get"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
]
}
Para interagir com orquestradores, a função deve incluir uma associação de entrada durableClient.
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 construtor DurableOrchestrationClient para criar um cliente Durable Functions. Use o cliente para iniciar uma orquestração e retornar uma resposta HTTP que inclua URLs para verificar o status da nova orquestração.
Exemplo do PowerShell em breve.
Exemplo de Java em breve.
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.
import {
DurableTaskAzureManagedClientBuilder,
} from "@microsoft/durabletask-js-azuremanaged";
const connectionString =
process.env.DURABLE_TASK_SCHEDULER_CONNECTION_STRING ||
"Endpoint=http://localhost:8080;Authentication=None;TaskHub=default";
const client = new DurableTaskAzureManagedClientBuilder()
.connectionString(connectionString)
.build();
// Schedule a new orchestration instance
const instanceId = await client.scheduleNewOrchestration(greetingOrchestrator, "World");
console.log(`Started orchestration with ID: ${instanceId}`);
// Wait for the orchestration to complete
const state = await client.waitForOrchestrationCompletion(instanceId, true, 30);
console.log(`Orchestration completed with result: ${state?.serializedOutput}`);
Crie o DurableTaskAzureManagedClientBuilder usando uma cadeia de conexão para o Agendador de Tarefas Duráveis. Use scheduleNewOrchestration para iniciar uma orquestração e waitForOrchestrationCompletion aguardar a conclusão.
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Create the client
client = DurableTaskSchedulerClient(
host_address=endpoint,
secure_channel=endpoint != "http://localhost:8080",
taskhub=taskhub_name,
token_credential=credential
)
# Schedule a new orchestration instance
instance_id = client.schedule_new_orchestration(
function_chaining_orchestrator,
input="World"
)
print(f"Started orchestration with ID: {instance_id}")
# Wait for the orchestration to complete
result = client.wait_for_orchestration_completion(instance_id, timeout=60)
if result and result.runtime_status == "COMPLETED":
print(f"Orchestration completed with result: {result.serialized_output}")
O DurableTaskSchedulerClient conecta ao Agendador de Tarefas Duráveis. Use schedule_new_orchestration para iniciar uma orquestração e wait_for_orchestration_completion aguardar a conclusão.
Este exemplo é mostrado para .NET, JavaScript, Java e Python.
import java.time.Duration;
import com.microsoft.durabletask.DurableTaskClient;
import com.microsoft.durabletask.NewOrchestrationInstanceOptions;
import com.microsoft.durabletask.OrchestrationMetadata;
import com.microsoft.durabletask.azuremanaged.DurableTaskSchedulerClientExtensions;
// Create the client
DurableTaskClient client = DurableTaskSchedulerClientExtensions
.createClientBuilder(connectionString)
.build();
// Schedule a new orchestration instance
String instanceId = client.scheduleNewOrchestrationInstance(
"ActivityChaining",
new NewOrchestrationInstanceOptions().setInput("Hello, world!"));
System.out.println("Started orchestration with ID: " + instanceId);
// Wait for the orchestration to complete
OrchestrationMetadata result = client.waitForInstanceCompletion(
instanceId,
Duration.ofSeconds(30),
true);
System.out.println("Orchestration completed with result: " + result.readOutputAs(String.class));
Crie o DurableTaskClient usando um connection string. Use scheduleNewOrchestrationInstance para iniciar uma orquestração e waitForInstanceCompletion 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:
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
Inicie o trabalho para registrar o orquestrador e atividades.
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.