Funktionslänkning i Durable Functions – Hello-sekvensexempel
Artikel
Funktionslänkning refererar till mönstret för att köra en sekvens med funktioner i en viss ordning. Ofta måste utdata från en funktion tillämpas på indata från en annan funktion. Den här artikeln beskriver den länkningssekvens som du skapar när du slutför snabbstarten durable functions (C#, JavaScript, TypeScript, Python, PowerShell eller Java). Mer information om Durable Functions finns i Översikt över Durable Functions.
Version 4 av Node.js programmeringsmodellen för Azure Functions är allmänt tillgänglig. Den nya v4-modellen är utformad för att ha en mer flexibel och intuitiv upplevelse för JavaScript- och TypeScript-utvecklare. Läs mer om skillnaderna mellan v3 och v4 i migreringsguiden.
I följande kodfragment anger JavaScript (PM4) programmeringsmodellen V4, den nya upplevelsen.
Funktionerna
I den här artikeln beskrivs följande funktioner i exempelappen:
E1_HelloSequence: En orkestreringsfunktion som anropar E1_SayHello flera gånger i en sekvens. Den lagrar utdata från anropen E1_SayHello och registrerar resultatet.
E1_SayHello: En aktivitetsfunktion som förbereder en sträng med "Hello".
Alla C#-orkestreringsfunktioner måste ha en parameter av typen DurableOrchestrationContext, som finns i Microsoft.Azure.WebJobs.Extensions.DurableTask sammansättningen. Med det här kontextobjektet kan du anropa andra aktivitetsfunktioner och skicka indataparametrar med hjälp av dess CallActivityAsync metod.
Koden anropar E1_SayHello tre gånger i följd med olika parametervärden. Returvärdet för varje anrop läggs till i outputs listan, som returneras i slutet av funktionen.
function.json
Om du använder Visual Studio Code eller Azure-portalen för utveckling, här är innehållet i function.json-filen för orchestrator-funktionen. De flesta orchestrator function.json filer ser nästan exakt ut så här.
Det viktiga är bindningstypen orchestrationTrigger . Alla orkestreringsfunktioner måste använda den här utlösartypen.
Varning
Använd inga indata- eller utdatabindningar när du använder orchestrationTrigger utlösarbindningen för att följa regeln "ingen I/O"-regel för orchestrator-funktioner. Om andra indata- eller utdatabindningar behövs bör de i stället användas i kontexten för activityTrigger funktioner som anropas av orkestratorn. Mer information finns i artikeln om begränsningar för orchestrator-funktionskod .
Alla JavaScript-orkestreringsfunktioner måste innehålla modulendurable-functions. Det är ett bibliotek som gör att du kan skriva Durable Functions i JavaScript. Det finns tre betydande skillnader mellan en orkestreringsfunktion och andra JavaScript-funktioner:
Funktionen omsluts i ett anrop till modulens durable-functionsorchestrator metod (här df).
Funktionen måste vara synkron. Eftersom metoden "orchestrator" hanterar det sista anropet till "context.done" bör funktionen helt enkelt "returnera".
Objektet context innehåller ett df varaktigt orkestreringskontextobjekt som låter dig anropa andra aktivitetsfunktioner och skicka indataparametrar med hjälp av dess callActivity metod. Koden anropar E1_SayHello tre gånger i följd med olika parametervärden, med hjälp av yield för att indikera att körningen ska vänta på att asynkrona aktivitetsfunktionsanrop returneras. Returvärdet för varje anrop läggs till i matrisen outputs , som returneras i slutet av funktionen.
Alla JavaScript-orkestreringsfunktioner måste innehålla modulendurable-functions. Med den här modulen kan du skriva Durable Functions i JavaScript. Om du vill använda V4-nodprogrammeringsmodellen måste du installera förhandsversionen v3.x av durable-functions.
Det finns två betydande skillnader mellan en orkestreringsfunktion och andra JavaScript-funktioner:
Funktionen måste vara synkron. Funktionen bör helt enkelt "returnera".
Objektet context innehåller ett df varaktigt orkestreringskontextobjekt som låter dig anropa andra aktivitetsfunktioner och skicka indataparametrar med hjälp av dess callActivity metod. Koden anropar sayHello tre gånger i följd med olika parametervärden, med hjälp av yield för att indikera att körningen ska vänta på att asynkrona aktivitetsfunktionsanrop returneras. Returvärdet för varje anrop läggs till i matrisen outputs , som returneras i slutet av funktionen.
Kommentar
Python Durable Functions är endast tillgängligt för Functions 3.0-körning.
function.json
Om du använder Visual Studio Code eller Azure-portalen för utveckling, här är innehållet i function.json-filen för orchestrator-funktionen. De flesta orchestrator function.json filer ser nästan exakt ut så här.
Det viktiga är bindningstypen orchestrationTrigger . Alla orkestreringsfunktioner måste använda den här utlösartypen.
Varning
Använd inga indata- eller utdatabindningar när du använder orchestrationTrigger utlösarbindningen för att följa regeln "ingen I/O"-regel för orchestrator-funktioner. Om andra indata- eller utdatabindningar behövs bör de i stället användas i kontexten för activityTrigger funktioner som anropas av orkestratorn. Mer information finns i artikeln om begränsningar för orchestrator-funktionskod .
Alla Python-orkestreringsfunktioner måste innehålla durable-functions paketet. Det är ett bibliotek där du kan skriva Durable Functions i Python. Det finns två betydande skillnader mellan en orkestreringsfunktion och andra Python-funktioner:
Filen bör registrera orchestrator-funktionen som orkestreringsfunktion genom att ange main = df.Orchestrator.create(<orchestrator function name>) i slutet av filen. Detta hjälper till att skilja den från andra hjälpfunktioner som deklarerats i filen.
Med context objektet kan du anropa andra aktivitetsfunktioner och skicka indataparametrar med hjälp av dess call_activity metod. Koden anropar E1_SayHello tre gånger i följd med olika parametervärden, med hjälp av yield för att indikera att körningen ska vänta på att asynkrona aktivitetsfunktionsanrop returneras. Returvärdet för varje anrop returneras i slutet av funktionen.
[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
Aktiviteter använder attributet ActivityTrigger . Använd angivet IDurableActivityContext för att utföra aktivitetsrelaterade åtgärder, till exempel åtkomst till indatavärdet med hjälp av GetInput<T>.
Implementeringen av E1_SayHello är en relativt trivial strängformateringsåtgärd.
I stället för att binda till en IDurableActivityContextkan du binda direkt till den typ som skickas till aktivitetsfunktionen. Till exempel:
Den function.json filen för aktivitetsfunktionen E1_SayHello liknar E1_HelloSequence den för förutom att den använder en activityTrigger bindningstyp i stället för en orchestrationTrigger bindningstyp.
Alla aktivitetsfunktioner som anropas av en orkestreringsfunktion måste använda bindningen activityTrigger .
Implementeringen av E1_SayHello är en relativt trivial strängformateringsåtgärd.
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
Till skillnad från orkestreringsfunktionen behöver en aktivitetsfunktion ingen särskild konfiguration. Indata som skickas till den av orchestrator-funktionen finns på objektet under namnet på context.bindings bindningen activityTrigger – i det här fallet context.bindings.name. Bindningsnamnet kan anges som en parameter för den exporterade funktionen och nås direkt, vilket är vad exempelkoden gör.
Implementeringen av sayHello är en relativt trivial strängformateringsåtgärd.
Till skillnad från orkestreringsfunktionen behöver en aktivitetsfunktion ingen särskild konfiguration. Indata som skickas till den av orchestrator-funktionen är det första argumentet till funktionen. Det andra argumentet är anropskontexten, som inte används i det här exemplet.
E1_SayHello/function.json
Den function.json filen för aktivitetsfunktionen E1_SayHello liknar E1_HelloSequence den för förutom att den använder en activityTrigger bindningstyp i stället för en orchestrationTrigger bindningstyp.
Till skillnad från orkestreringsfunktionen behöver en aktivitetsfunktion ingen särskild konfiguration. De indata som skickas till den av orchestrator-funktionen är direkt åtkomliga som parametern för funktionen.
HttpStart-klientfunktion
Du kan starta en instans av orchestrator-funktionen med hjälp av en klientfunktion. Du använder den HttpStart HTTP-utlösta funktionen för att starta instanser av 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);
}
}
För att interagera med orkestrerare måste funktionen innehålla en DurableClient indatabindning. Du använder klienten för att starta en orkestrering. Det kan också hjälpa dig att returnera ett HTTP-svar som innehåller URL:er för att kontrollera status för den nya orkestreringen.
Använd df.getClient för att hämta ett DurableOrchestrationClient objekt. Du använder klienten för att starta en orkestrering. Det kan också hjälpa dig att returnera ett HTTP-svar som innehåller URL:er för att kontrollera status för den nya orkestreringen.
För att hantera och interagera med orkestrerare behöver funktionen en durableClient indatabindning. Den här bindningen måste anges i extraInputs argumentet när funktionen registreras. Du durableClient kan hämta indata genom att anropa df.input.durableClient().
Använd df.getClient för att hämta ett DurableClient objekt. Du använder klienten för att starta en orkestrering. Det kan också hjälpa dig att returnera ett HTTP-svar som innehåller URL:er för att kontrollera status för den nya orkestreringen.
För att interagera med orkestrerare måste funktionen innehålla en durableClient indatabindning.
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)
DurableOrchestrationClient Använd konstruktorn för att hämta en Durable Functions-klient. Du använder klienten för att starta en orkestrering. Det kan också hjälpa dig att returnera ett HTTP-svar som innehåller URL:er för att kontrollera status för den nya orkestreringen.
Kör exemplet
Skicka följande HTTP POST-begäran till HttpStart funktionen för att köra E1_HelloSequence orkestreringen.
POST http://{host}/orchestrators/E1_HelloSequence
Kommentar
Det tidigare HTTP-kodfragmentet förutsätter att det finns en post i host.json filen som tar bort standardprefixet api/ från alla URL:er för HTTP-utlösare. Du hittar markering för den här konfigurationen host.json i filen i exemplen.
Om du till exempel kör exemplet i en funktionsapp med namnet "myfunctionapp" ersätter du {host} med "myfunctionapp.azurewebsites.net".
Resultatet är ett HTTP 202-svar, så här (trimmat för korthet):
Nu placeras orkestreringen i kö och börjar köras omedelbart. URL:en i Location rubriken kan användas för att kontrollera körningens status.
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
Resultatet är orkestreringens status. Den körs och slutförs snabbt, så du ser den i tillståndet Slutförd med ett svar som ser ut så här (trimmat för korthet):
Som du ser är instansen runtimeStatus Slutförd och output innehåller det JSON-serialiserade resultatet av orchestrator-funktionskörningen.
Kommentar
Du kan implementera liknande startlogik för andra utlösartyper, till exempel queueTrigger, eventHubTriggereller timerTrigger.
Titta på funktionskörningsloggarna. Funktionen E1_HelloSequence startades och slutfördes flera gånger på grund av det uppspelningsbeteende som beskrivs i avsnittet om orkestreringstillförlitlighet . Å andra sidan fanns det bara tre körningar av E1_SayHello eftersom dessa funktionskörningar inte spelas upp igen.
Nästa steg
Det här exemplet har visat en enkel funktionslänkningsorkestrering. Nästa exempel visar hur du implementerar mönstret-out/-in.