Il concatenamento delle funzioni è un modello in cui si esegue una sequenza di funzioni in ordine. È comune passare l'output di una funzione all'input del successivo. Questo articolo descrive la sequenza di concatenamento creata al termine della guida introduttiva Durable Functions (C#, JavaScriptTypeScript, Python, PowerShell o Java). Per ulteriori informazioni, consulta la panoramica di Durable Functions.
Prerequisiti
Modello di programmazione V3
Modello di programmazione V4
Il concatenamento delle funzioni è un modello in cui si esegue una sequenza di attività in ordine. È comune passare l'output di un'attività all'input del successivo. Questo articolo descrive l'ordine di concatenamento per gli SDK di Task Durable per .NET, JavaScript, Python e Java.
Funzioni
Questo articolo descrive queste funzioni nell'app di esempio:
Questo articolo descrive questi componenti nell'app di esempio:
-
GreetingOrchestration, greetingOrchestrator, function_chaining_orchestratoro ActivityChaining: agente di orchestrazione che chiama più attività in sequenza. Archivia ogni output e registra i risultati.
- Funzioni di attività: attività che elaborano l'input e restituiscono risultati. Ogni attività esegue una semplice trasformazione sull'input.
- Client: un'app client che avvia un'istanza dell'agente di orchestrazione e attende il risultato ottenuto.
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;
}
Tutte le funzioni di orchestrazione C# devono avere un parametro di tipo DurableOrchestrationContext, che esiste nell'assembly Microsoft.Azure.WebJobs.Extensions.DurableTask. Questo contesto di ambiente consente di chiamare altre funzioni dell’attività e di passare i parametri di input usando il metodo CallActivityAsync.
Il codice chiama E1_SayHello tre volte in sequenza con valori dei parametri diversi. Il valore restituito di ogni chiamata viene aggiunto all'elenco outputs, che viene restituito al termine della funzione.
Modello di programmazione V3
function.json
Se si sviluppa in Visual Studio Code o nel portale di Azure, ecco il file dell'agente di orchestrazione function.json.
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
],
"disabled": false
}
L'impostazione principale è il orchestrationTrigger tipo di associazione. Tutte le funzioni di orchestrazione devono usare questo tipo di trigger.
Avviso
Per seguire la regola "no I/O" per le funzioni dell'orchestratore, non usare associazioni di input o output con l'associazione trigger orchestrationTrigger. Se sono necessarie altre associazioni di input o output, usarle nelle activityTrigger funzioni chiamate dall'agente di orchestrazione. Per altre informazioni, vedere Vincoli di codice della funzione di orchestrazione.
index.js
La funzione dell'orchestratore è la seguente:
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;
});
Tutte le funzioni di orchestrazione JavaScript devono includere il modulo durable-functions. Si tratta di una libreria che consente di scrivere Durable Functions in JavaScript. Tre differenze principali tra una funzione dell'agente di orchestrazione e altre funzioni JavaScript:
- La funzione dell'agente di orchestrazione è una funzione del generatore.
- La funzione viene incapsulata in una chiamata al metodo
orchestrator del modulo durable-functions (qui df).
- La funzione è sincrona. Poiché il
orchestrator metodo chiama context.done, la funzione restituisce .
L'oggetto context contiene un contesto di ambiente di orchestrazione durevole df che consente di chiamare altre funzioni dell’attività e di passare parametri di input con il metodo callActivity. Il codice chiama E1_SayHello tre volte in sequenza con valori di parametro diversi, usando yield per indicare che l'esecuzione deve attendere la restituzione delle chiamate di funzioni di attività asincrone. Il valore restituito di ogni chiamata viene aggiunto all'array outputs, che viene restituito al termine della funzione.
Modello di programmazione 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;
});
Tutte le funzioni di orchestrazione JavaScript devono includere il modulo durable-functions. Questo modulo consente di scrivere Durable Functions in JavaScript. Per usare il modello di programmazione dei nodi V4, è necessario installare la v3.x versione di durable-functions.
Due differenze principali tra una funzione dell'agente di orchestrazione e altre funzioni JavaScript:
- La funzione dell'agente di orchestrazione è una funzione del generatore.
- La funzione è sincrona. La funzione restituisce.
L'oggetto context contiene un contesto di ambiente di orchestrazione durevole df che consente di chiamare altre funzioni dell’attività e di passare parametri di input con il metodo callActivity. Il codice chiama sayHello tre volte in sequenza con valori di parametro diversi, usando yield per indicare che l'esecuzione deve attendere la restituzione delle chiamate di funzioni di attività asincrone. Il valore restituito di ogni chiamata viene aggiunto all'array outputs, che viene restituito al termine della funzione.
Nota
Python Durable Functions sono disponibili solo per il runtime delle Funzioni 3.0.
function.json
Se si usa Visual Studio Code o il portale di Azure per lo sviluppo, ecco il contenuto del file function.json per la funzione dell'agente di orchestrazione. La maggior parte dei file function.json dell'agente di orchestrazione sono quasi identici a questo.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
Fondamentale è il tipo di associazione orchestrationTrigger. Tutte le funzioni di orchestrazione devono usare questo tipo di trigger.
Avviso
Per rispettare la regola "no I/O" delle funzioni di orchestrazione, non usare associazioni di input o output quando si usa l'associazione di trigger orchestrationTrigger. Quando sono necessarie altre associazioni di input o output, occorre invece usarle nel contesto delle funzioni activityTrigger già chiamate dall'agente di orchestrazione. Per altre informazioni, vedere l'articolo Vincoli di codice delle funzioni dell'agente di orchestrazione.
__init__.py
La funzione dell'orchestratore è la seguente:
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)
Tutte le funzioni di orchestrazione Python devono includere il pacchetto durable-functions. Si tratta di una libreria che consente di scrivere Durable Functions in Python. Due differenze principali tra una funzione dell'agente di orchestrazione e altre funzioni Python:
- La funzione dell'agente di orchestrazione è una funzione del generatore.
- Il file registra la funzione dell'agente di orchestrazione dichiarando
main = df.Orchestrator.create(<orchestrator function name>) alla fine del file. Ciò consente di distinguerlo da altre funzioni helper dichiarate nel file.
L'oggetto context consente di chiamare altre funzioni dell’attività e di passare parametri di input tramite il metodo call_activity. Il codice chiama E1_SayHello tre volte in sequenza con valori di parametro diversi, usando yield per indicare che l'esecuzione deve attendere la restituzione delle chiamate di funzioni di attività asincrone. Il valore restituito di ogni chiamata viene restituito alla fine della funzione.
L'esempio di PowerShell non è ancora disponibile.
Java esempio non è ancora disponibile.
Questo codice mostra un agente di orchestrazione che chiama tre attività in sequenza e passa ogni output all'attività successiva:
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;
}
}
Tutti gli orchestratori .NET ereditano da TaskOrchestrator<TInput, TOutput>.
TaskOrchestrationContext Consente di chiamare le attività usando CallActivityAsync. Il codice chiama tre attività in sequenza, in cui ogni attività riceve l'output dell'attività precedente.
Il codice seguente mostra un agente di orchestrazione che chiama tre attività in sequenza:
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;
};
Tutti gli agenti di orchestrazione JavaScript sono funzioni generatori (async function*) che usano yield per chiamare le attività. Il metodo callActivity del contesto di orchestrazione pianifica l'esecuzione dell'attività. Il codice chiama tre attività in sequenza, passando l'output di ogni attività alla successiva.
Il codice seguente mostra un agente di orchestrazione che chiama tre attività in sequenza:
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
Tutti gli agenti di orchestrazione Python sono funzioni generatori che usano yield per chiamare le attività. Il metodo call_activity del contesto di orchestrazione pianifica l'esecuzione dell'attività. Il codice chiama tre attività in sequenza, passando l'output di ogni attività alla successiva.
Questo esempio viene illustrato per .NET, JavaScript, Java e Python.
Il codice seguente mostra un agente di orchestrazione che chiama tre attività in sequenza:
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();
In Java gli agenti di orchestrazione vengono definiti usando TaskOrchestrationFactory. Il metodo del contesto pianifica l'esecuzione dell'attività callActivity e await() attende il risultato. Il codice chiama tre attività in sequenza, passando l'output di ogni attività alla successiva.
Activity
[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
Le attività usano l'attributo ActivityTrigger. Usare IDurableActivityContext per le azioni di attività, ad esempio la lettura dell'input con GetInput<T>.
E1_SayHello formatta una stringa di saluto.
Anziché eseguire l'associazione a IDurableActivityContext, eseguire l'associazione direttamente al tipo passato alla funzione dell'attività. Ad esempio:
[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
return $"Hello {name}!";
}
Modello di programmazione V3
E1_SayHello/function.json
Il file function.json per la funzione di attività E1_SayHello è simile a quello di E1_HelloSequence ad eccezione del fatto che usa un tipo di associazione activityTrigger anziché un tipo di associazione orchestrationTrigger.
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
],
"disabled": false
}
Nota
Usare l'associazione activityTrigger per tutte le funzioni di attività chiamate da una funzione di orchestrazione.
L'implementazione di E1_SayHello è un'operazione di formattazione delle stringhe relativamente semplice.
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
A differenza della funzione di orchestrazione, una funzione di attività non richiede una configurazione speciale. L'orchestratore passa l'input all'oggetto context.bindings sotto il nome del binding activityTrigger, in questo caso context.bindings.name. Impostare il nome del binding come parametro della funzione esportata per accedervi direttamente, come avviene nell'esempio.
Modello di programmazione V4
sayHello formatta una stringa di saluto.
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.activity(helloActivityName, {
handler: function (input) {
return `Hello ${input}`;
},
});
A differenza della funzione di orchestrazione, una funzione di attività non richiede una configurazione speciale. L'orchestratore passa l'input come primo argomento alla funzione. Il secondo argomento è il contesto di chiamata, che questo esempio non usa.
E1_SayHello/function.json
Il file function.json per la funzione di attività E1_SayHello è simile a quello di E1_HelloSequence ad eccezione del fatto che usa un tipo di associazione activityTrigger anziché un tipo di associazione orchestrationTrigger.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
]
}
Nota
Tutte le funzioni dell’attività chiamate da una funzione di orchestrazione devono usare l'associazione activityTrigger.
L'implementazione di E1_SayHello è un'operazione di formattazione delle stringhe relativamente semplice.
E1_SayHello/__init__.py
def main(name: str) -> str:
return f"Hello {name}!"
A differenza della funzione di orchestrazione, una funzione dell’attività non richiede alcuna configurazione speciale. L'input passato alla funzione di orchestrazione è accessibile direttamente come parametro per la funzione.
L'esempio di PowerShell sarà presto disponibile.
Java esempio presto disponibile.
Le attività in Durable Task SDK ereditano da 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!");
}
}
Utilizzare l'inserimento delle dipendenze per ottenere servizi come ILogger. Aggiungere l'attributo [DurableTask] per registrare l'attività con il worker.
Le attività in Durable Task SDK sono funzioni semplici:
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!`;
};
A differenza degli agenti di orchestrazione, le attività possono eseguire operazioni di I/O come chiamate HTTP, query di database e accesso ai file. L'input viene passato direttamente come parametro.
Le attività in Durable Task SDK sono funzioni semplici:
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!"
A differenza degli agenti di orchestrazione, le attività possono eseguire operazioni di I/O come chiamate HTTP, query di database e accesso ai file. L'input viene passato direttamente come parametro.
Questo esempio viene illustrato per .NET, JavaScript, Java e Python.
Le attività in Java vengono definite 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", "-");
};
}
})
Registrare ogni attività con il generatore di ruoli di lavoro usando addActivity. Le attività possono eseguire operazioni di I/O e restituire risultati all'agente di orchestrazione.
Cliente
Avviare un'istanza della funzione di orchestrazione da una funzione client. Usare la HttpStart funzione attivata da HTTP per avviare le istanze di 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);
}
}
Per interagire con gli orchestratori, aggiungere un'associazione DurableClient di input. Usare il client per avviare un'orchestrazione e restituire una risposta HTTP che include GLI URL per controllare lo stato della nuova orchestrazione.
Modello di programmazione 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
}
Per interagire con gli orchestratori, aggiungere un binding di input durableClient.
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);
};
Utilizzare df.getClient per ottenere un DurableOrchestrationClient oggetto . Usare il client per avviare un'orchestrazione e restituire una risposta HTTP che include GLI URL per controllare lo stato della nuova orchestrazione.
Modello di programmazione 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);
},
});
Per gestire e interagire con orchestratori, aggiungere un'associazione durableClient di input. Specificare l'associazione nell'argomento extraInputs quando si registra la funzione. Ottenere l'input durableClient chiamando df.input.durableClient().
Utilizzare df.getClient per ottenere un DurableClient oggetto . Usare il client per avviare un'orchestrazione e restituire una risposta HTTP che include GLI URL per controllare lo stato della nuova orchestrazione.
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"
}
]
}
Per interagire con gli orchestratori, la funzione deve includere un'associazione di input 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)
Usare il costruttore DurableOrchestrationClient per creare un client Durable Functions. Usare il client per avviare un'orchestrazione e restituire una risposta HTTP che include GLI URL per controllare lo stato della nuova orchestrazione.
L'esempio di PowerShell sarà presto disponibile.
Java esempio presto disponibile.
Avviare un'orchestrazione da un'applicazione client. Il client pianifica l'orchestrazione e può attendere il completamento.
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>()}");
Creare il DurableTaskClient usando una stringa di connessione al pianificatore di attività durevole. Usare ScheduleNewOrchestrationInstanceAsync per avviare un'orchestrazione e WaitForInstanceCompletionAsync attendere il completamento.
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}`);
Creare il DurableTaskAzureManagedClientBuilder usando una stringa di connessione al pianificatore di attività durevole. Usare scheduleNewOrchestration per avviare un'orchestrazione e waitForOrchestrationCompletion attendere il completamento.
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}")
DurableTaskSchedulerClient si connette al pianificatore di attività durevoli. Usare schedule_new_orchestration per avviare un'orchestrazione e wait_for_orchestration_completion attendere il completamento.
Questo esempio viene illustrato per .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));
Creare il DurableTaskClient usando un connection string. Usare scheduleNewOrchestrationInstance per avviare un'orchestrazione e waitForInstanceCompletion attendere il completamento.
Esegui l'esempio
Per eseguire l'orchestrazione E1_HelloSequence , inviare questa richiesta HTTP POST alla HttpStart funzione.
POST http://{host}/orchestrators/E1_HelloSequence
Nota
Il frammento HTTP precedente presuppone che il file dihost.json dell'esempio rimuova il prefisso predefinito api/ da tutti gli URL della funzione trigger HTTP. Trova questa configurazione nel file host.json dell'esempio.
Ad esempio, se si esegue l'esempio in un'app per le funzioni denominata myfunctionapp, sostituire {host} con myfunctionapp.azurewebsites.net.
La richiesta restituisce HTTP 202 (tagliata per brevità):
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...)
Le code di orchestrazione iniziano immediatamente l'esecuzione. Usare l'URL nell'intestazione Location per controllare lo stato di esecuzione.
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
La risposta mostra lo stato dell'orchestrazione. Poiché termina rapidamente, l'istanza è spesso nello stato Completato e restituisce una risposta simile alla seguente (tagliata per brevità):
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"}
L'istanza runtimeStatus è Completed e output contiene il risultato serializzato JSON dell'esecuzione della funzione dell'agente di orchestrazione.
Nota
Implementare una logica di avvio simile per altri tipi di trigger, ad esempio queueTrigger, eventHubTriggero timerTrigger.
Esaminare i log di esecuzione della funzione. La E1_HelloSequence funzione viene avviata e completata più volte a causa del comportamento di riproduzione descritto in Affidabilità dell'orchestrazione. Ma E1_SayHello viene eseguito solo tre volte perché le esecuzioni delle funzioni di attività non vengono riprodotte.
Per eseguire l'esempio, è necessario:
Avvia l'emulatore del pianificatore di attività durevoli (per lo sviluppo locale):
docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latest
Avvia il worker per registrare l'orchestratore e le attività.
Eseguire il client per pianificare un'orchestrazione e attendere il risultato.
L'output del client mostra il risultato concatenato dell'orchestrazione:
Started orchestration with ID: abc123
Orchestration completed with result: "Hello World! How are you today? I hope you're doing well!"
I log di lavoro mostrano ogni attività eseguita in sequenza e ne passa l'output all'attività successiva.
Passaggi successivi
Questo esempio illustra una semplice orchestrazione del concatenamento di funzioni. Implementare quindi il modello fan-out/fan-in.
Questo esempio illustra una semplice orchestrazione del concatenamento di funzioni. Successivamente, esplorare altri modelli.
Per esempi completi di JavaScript SDK, vedere gli esempi di Durable Task JavaScript SDK.