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
Modelo de programação V3
Modelo de programação V4
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.
Modelo de programação V3
function.json
Se desenvolveres no Visual Studio Code ou no portal Azure, aqui está o ficheiro orquestrador function.json.
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
],
"disabled": false
}
A definição chave é o tipo de ligação orchestrationTrigger. Todas as funções do orquestrador devem usar esse tipo de gatilho.
Aviso
Para seguir a regra "sem E/S" para funções de orquestrador, não use ligações de entrada ou saída com a ligação de disparo orchestrationTrigger. Se precisares de outras ligações de entrada ou saída, usa-as em activityTrigger funções que o orquestrador chama. Para mais informações, consulte as restrições do código de funções do orquestrador.
index.js
Aqui está a função de orquestração:
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 JavaScript devem incluir o durable-functions módulo. É uma biblioteca que permite escrever Durable Functions em JavaScript. Três diferenças chave entre uma função de orquestrador e outras funções JavaScript:
- A função orquestradora é uma função geradora.
- A função é envolvida em uma chamada ao método
orchestrator do módulo durable-functions (aqui df).
- A função é síncrona. Como o
orchestrator método chama context.done, a função devolve.
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 que as chamadas de função de atividade assíncrona sejam retornadas. O valor de retorno de cada chamada é adicionado à outputs matriz, que é retornada no 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 JavaScript devem incluir o durable-functions módulo. Este módulo permite-lhe escrever Durable Functions em JavaScript. Para usar o modelo de programação de nós V4, é necessário instalar a v3.x versão de durable-functions.
Duas diferenças-chave entre uma função de orquestrador e outras funções JavaScript:
- A função orquestradora é uma função geradora.
- A função é síncrona. A função retorna.
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 que as chamadas de função de atividade assíncrona sejam retornadas. O valor de retorno de cada chamada é adicionado à outputs matriz, que é retornada no final da função.
Nota
As Python Durable Functions estão disponíveis apenas no runtime Functions 3.0.
function.json
Se usares Visual Studio Code ou o portal Azure para desenvolvimento, aqui está o conteúdo do ficheiro function.json para a função de orquestrador. A maioria dos ficheiros orquestrador function.json se parecem quase exatamente com isto.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
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 as restrições de código da função de orchestrator.
__init__.py
Aqui está a função de orquestração:
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 escrever Durable Functions em Python. Duas diferenças-chave entre uma função de orquestrador e outras funções em Python:
- A função orquestradora é uma função geradora.
- O ficheiro regista a função do orquestrador indicando
main = df.Orchestrator.create(<orchestrator function name>) no final do ficheiro. Isto ajuda a distingui-lo de outras funções auxiliares declaradas no ficheiro.
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 que as chamadas de função de atividade assíncrona sejam retornadas. O valor de retorno de cada chamada é retornado no final da função.
O exemplo do PowerShell ainda não está disponível.
O exemplo de Java ainda não está disponível.
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.
O código seguinte 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 geradoras (async function*) que usam yield para chamar atividades. O método do contexto de orquestração callActivity 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 seguinte.
O código seguinte 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 do contexto de orquestração call_activity 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 seguinte.
Este exemplo é mostrado para .NET, JavaScript, Java e Python.
O código seguinte mostra um orquestrador que chama três atividades em sequência:
import com.microsoft.durabletask.*;
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 callActivity contexto agenda a execução da atividade e await() espera pelo resultado. O código chama três atividades em sequência, passando a saída de cada atividade para a seguinte.
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}!";
}
Modelo de programação V3
E1_SayHello/function.json
O ficheiro function.json para a função de atividade E1_SayHello é semelhante ao de E1_HelloSequence exceto que usa um tipo de ligação activityTrigger em vez de um tipo de ligação orchestrationTrigger.
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
],
"disabled": false
}
Nota
Utilize o activityTrigger binding 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 texto 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 necessita de configuração especial. O orquestrador passa a entrada para o objeto context.bindings sob o nome da associação activityTrigger—neste caso, context.bindings.name. Defina o nome de ligação como parâmetro da função exportada para aceder a ela diretamente, tal como no exemplo.
Modelo de programação V4
sayHello Formata uma cadeia de cumprimentos.
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 necessita de configuração especial. O orquestrador passa a entrada como primeiro argumento da função. O segundo argumento é o contexto de invocação, que este exemplo não utiliza.
E1_SayHello/function.json
O arquivo function.json para a função de atividade E1_SayHello é semelhante ao de E1_HelloSequence, exceto que ele usa um tipo de ligação activityTrigger em vez de um tipo de ligação orchestrationTrigger.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
]
}
Nota
Todas as funções de atividade chamadas por uma função de orquestração devem usar o activityTrigger binding.
A implementação de E1_SayHello é uma operação de formatação de string relativamente trivial.
E1_SayHello/__init__.py
def main(name: str) -> str:
return f"Hello {name}!"
Ao contrário da função orquestradora, uma função de atividade não precisa de configuração especial. A entrada passada para a função pelo orquestrador é diretamente acessível como um parâmetro para a função.
Exemplo de PowerShell em breve.
Exemplo de Java em breve.
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.
As atividades no SDK de Tarefas Duradouras 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 realizar operações de I/O como chamadas HTTP, consultas à base de dados e acesso a ficheiros. A entrada é passada diretamente como parâmetro.
As atividades no SDK de Tarefas Duradouras 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 realizar operações de I/O como chamadas HTTP, consultas à base de dados e acesso a ficheiros. A entrada é passada diretamente como parâmetro.
Este exemplo é mostrado para .NET, JavaScript, Java e Python.
As atividades em Java são definidas usando TaskActivityFactory:
import com.microsoft.durabletask.*;
.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", "-");
};
}
})
Registe cada atividade com o construtor de worker usando addActivity. As atividades podem realizar operações de I/O e devolver resultados ao orquestrador.
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.
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 ligaçã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);
};
Usa df.getClient para conseguir um DurableOrchestrationClient objeto. Use o cliente para iniciar uma orquestração e retorne uma resposta HTTP que inclua URLs para verificar o estado 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 gerir e interagir com os orquestradores, adicione uma durableClient ligação de entrada. Especifique a ligação no extraInputs argumento quando regista a função. Obtenha o durableClient de entrada chamando df.input.durableClient().
Usa df.getClient para conseguir um DurableClient objeto. Use o cliente para iniciar uma orquestração e retorne uma resposta HTTP que inclua URLs para verificar o estado 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 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 construtor DurableOrchestrationClient para criar um cliente Durable Functions. Use o cliente para iniciar uma orquestração e retorne uma resposta HTTP que inclua URLs para verificar o estado da nova orquestração.
Exemplo de PowerShell em breve.
Exemplo de Java em breve.
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.
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 ligação com o Durable Task Scheduler. Use scheduleNewOrchestration para iniciar uma orquestração e waitForOrchestrationCompletion esperar pela 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 == OrchestrationStatus.COMPLETED:
print(f"Orchestration completed with result: {result.serialized_output}")
Liga-se DurableTaskSchedulerClient ao Durável Agendador de Tarefas. Use schedule_new_orchestration para iniciar uma orquestração e wait_for_orchestration_completion esperar pela conclusão.
Este exemplo é mostrado para .NET, JavaScript, Java e Python.
import com.microsoft.durabletask.*;
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));
Cria o DurableTaskClient usando um connection string. Use scheduleNewOrchestrationInstance para iniciar uma orquestração e waitForInstanceCompletion 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:
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
Inicie o worker para registar o orquestrador e as atividades.
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.