Łączenie funkcji w Durable Functions — przykład sekwencji hello
Artykuł
Łączenie funkcji odnosi się do wzorca wykonywania sekwencji funkcji w określonej kolejności. Często dane wyjściowe jednej funkcji muszą być stosowane do danych wejściowych innej funkcji. W tym artykule opisano sekwencję tworzenia łańcucha utworzoną po ukończeniu przewodnika Szybki start Durable Functions (C#, JavaScript, TypeScript, Python, PowerShell lub Java). Aby uzyskać więcej informacji na temat Durable Functions, zobacz omówienie Durable Functions.
Wersja 4 modelu programowania Node.js dla Azure Functions jest ogólnie dostępna. Nowy model w wersji 4 został zaprojektowany z myślą o bardziej elastycznym i intuicyjnym środowisku dla deweloperów języka JavaScript i TypeScript. Dowiedz się więcej o różnicach między wersjami 3 i 4 w przewodniku migracji.
W poniższych fragmentach kodu kod JavaScript (PM4) oznacza model programowania w wersji 4 , nowe środowisko.
Funkcje
W tym artykule wyjaśniono następujące funkcje w przykładowej aplikacji:
E1_HelloSequence: Funkcja orkiestratora , która wywołuje E1_SayHello wiele razy w sekwencji. Przechowuje dane wyjściowe z E1_SayHello wywołań i rejestruje wyniki.
E1_SayHello: funkcja działania , która poprzedza ciąg ciągiem "Hello".
HttpStart: funkcja klienta trwała wyzwalana przez protokół HTTP, która uruchamia wystąpienie orkiestratora.
Wszystkie funkcje orkiestracji języka C# muszą mieć parametr typu DurableOrchestrationContext, który istnieje w Microsoft.Azure.WebJobs.Extensions.DurableTask zestawie. Ten obiekt kontekstu umożliwia wywoływanie innych funkcji działania i przekazywanie parametrów wejściowych przy użyciu jego CallActivityAsync metody.
Kod wywołuje E1_SayHello trzy razy w sekwencji z różnymi wartościami parametrów. Zwracana wartość każdego wywołania jest dodawana do outputs listy, która jest zwracana na końcu funkcji.
function.json
Jeśli używasz Visual Studio Code lub Azure Portal do programowania, oto zawartość pliku function.json dla funkcji orkiestratora. Większość plików function.json programu orchestrator wygląda prawie dokładnie tak.
Ważnym elementem orchestrationTrigger jest typ powiązania. Wszystkie funkcje orkiestratora muszą używać tego typu wyzwalacza.
Ostrzeżenie
Aby przestrzegać reguły "brak we/wy" funkcji orkiestratora, nie używaj żadnych powiązań wejściowych ani wyjściowych podczas korzystania z orchestrationTrigger powiązania wyzwalacza. Jeśli potrzebne są inne powiązania wejściowe lub wyjściowe, powinny one być używane w kontekście activityTrigger funkcji, które są wywoływane przez orkiestrator. Aby uzyskać więcej informacji, zobacz artykuł dotyczący ograniczeń kodu funkcji orkiestratora .
Wszystkie funkcje orkiestracji języka JavaScript muszą zawierać durable-functions moduł. Jest to biblioteka, która umożliwia pisanie Durable Functions w języku JavaScript. Istnieją trzy znaczące różnice między funkcją orkiestratora a innymi funkcjami języka JavaScript:
Funkcja jest opakowana w wywołanie metody modułu durable-functionsorchestrator (tutaj df).
Funkcja musi być synchroniczna. Ponieważ metoda "orchestrator" obsługuje ostateczne wywołanie metody "context.done", funkcja powinna po prostu "zwrócić".
Obiekt context zawiera df trwały obiekt kontekstu orkiestracji, który umożliwia wywoływanie innych funkcji działania i przekazywanie parametrów wejściowych przy użyciu jego callActivity metody. Kod wywołuje E1_SayHello trzy razy w sekwencji z różnymi wartościami parametrów, używając polecenia yield , aby wskazać, że wykonanie powinno czekać na zwracane wywołania funkcji działania asynchronicznego. Zwracana wartość każdego wywołania jest dodawana do outputs tablicy, która jest zwracana na końcu funkcji.
Wszystkie funkcje orkiestracji języka JavaScript muszą zawierać durable-functions moduł. Ten moduł umożliwia pisanie Durable Functions w języku JavaScript. Aby użyć modelu programowania węzłów w wersji 4, należy zainstalować wersję zapoznawcza v3.x programu durable-functions.
Istnieją dwie znaczące różnice między funkcją orkiestratora a innymi funkcjami języka JavaScript:
Funkcja musi być synchroniczna. Funkcja powinna po prostu "zwrócić".
Obiekt context zawiera df trwały obiekt kontekstu orkiestracji, który umożliwia wywoływanie innych funkcji działania i przekazywanie parametrów wejściowych przy użyciu jego callActivity metody. Kod wywołuje sayHello trzy razy w sekwencji z różnymi wartościami parametrów, używając polecenia yield , aby wskazać, że wykonanie powinno czekać na zwracane wywołania funkcji działania asynchronicznego. Zwracana wartość każdego wywołania jest dodawana do outputs tablicy, która jest zwracana na końcu funkcji.
Uwaga
Durable Functions języka Python są dostępne tylko dla środowiska uruchomieniowego usługi Functions 3.0.
function.json
Jeśli używasz Visual Studio Code lub Azure Portal do programowania, oto zawartość pliku function.json dla funkcji orkiestratora. Większość plików function.json programu orchestrator wygląda prawie dokładnie tak.
Ważnym elementem orchestrationTrigger jest typ powiązania. Wszystkie funkcje orkiestratora muszą używać tego typu wyzwalacza.
Ostrzeżenie
Aby przestrzegać reguły "brak we/wy" funkcji orkiestratora, nie używaj żadnych powiązań wejściowych ani wyjściowych podczas korzystania z orchestrationTrigger powiązania wyzwalacza. Jeśli potrzebne są inne powiązania wejściowe lub wyjściowe, powinny one być używane w kontekście activityTrigger funkcji, które są wywoływane przez orkiestrator. Aby uzyskać więcej informacji, zobacz artykuł dotyczący ograniczeń kodu funkcji orkiestratora .
Wszystkie funkcje orkiestracji języka Python muszą zawierać durable-functions pakiet. Jest to biblioteka, która umożliwia pisanie Durable Functions w języku Python. Istnieją dwie znaczące różnice między funkcją orkiestratora a innymi funkcjami języka Python:
Plik powinien zarejestrować funkcję orkiestratora jako orkiestrator, stwierdzając main = df.Orchestrator.create(<orchestrator function name>) na końcu pliku. Pomaga to odróżnić go od innych, pomocników, funkcji zadeklarowanych w pliku.
Obiekt context umożliwia wywoływanie innych funkcji działania i przekazywanie parametrów wejściowych przy użyciu jego call_activity metody. Kod wywołuje E1_SayHello trzy razy w sekwencji z różnymi wartościami parametrów, używając polecenia yield , aby wskazać, że wykonanie powinno czekać na zwracane wywołania funkcji działania asynchronicznego. Wartość zwracana przez każde wywołanie jest zwracana na końcu funkcji.
[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
Działania używają atrybutu ActivityTrigger . Użyj podanego IDurableActivityContext elementu , aby wykonać akcje związane z działaniami, takie jak uzyskiwanie dostępu do wartości wejściowej przy użyciu polecenia GetInput<T>.
E1_SayHello Implementacja to stosunkowo trywialna operacja formatowania ciągów.
Zamiast wiązać z elementem , można powiązać bezpośrednio z typem IDurableActivityContextprzekazywanym do funkcji działania. Na przykład:
Plik function.json dla funkcji E1_SayHello activity jest podobny do tego z E1_HelloSequence wyjątkiem tego, że używa activityTrigger typu powiązania zamiast orchestrationTrigger typu powiązania.
Wszystkie funkcje działania wywoływane przez funkcję orkiestracji muszą używać activityTrigger powiązania.
E1_SayHello Implementacja to stosunkowo trywialna operacja formatowania ciągów.
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
W przeciwieństwie do funkcji orkiestracji funkcja działania nie wymaga specjalnej konfiguracji. Dane wejściowe przekazane do niego przez funkcję orkiestratora znajdują się w context.bindings obiekcie pod nazwą activityTrigger powiązania — w tym przypadku context.bindings.name. Nazwa powiązania można ustawić jako parametr wyeksportowanej funkcji i uzyskiwać do nich bezpośredni dostęp, czyli przykładowy kod.
sayHello Implementacja to stosunkowo trywialna operacja formatowania ciągów.
W przeciwieństwie do funkcji orkiestracji funkcja działania nie wymaga specjalnej konfiguracji. Dane wejściowe przekazane przez funkcję orkiestratora są pierwszym argumentem funkcji. Drugim argumentem jest kontekst wywołania, który nie jest używany w tym przykładzie.
E1_SayHello/function.json
Plik function.json dla funkcji E1_SayHello activity jest podobny do tego z E1_HelloSequence wyjątkiem tego, że używa activityTrigger typu powiązania zamiast orchestrationTrigger typu powiązania.
W przeciwieństwie do funkcji orkiestratora funkcja działania nie wymaga specjalnej konfiguracji. Dane wejściowe przekazane przez funkcję orkiestratora są bezpośrednio dostępne jako parametr funkcji.
HttpStart, funkcja klienta
Możesz uruchomić wystąpienie funkcji orkiestratora przy użyciu funkcji klienta. Użyjesz HttpStart funkcji wyzwalanej przez protokół HTTP, aby uruchomić wystąpienia programu 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);
}
}
Aby korzystać z orkiestratorów, funkcja musi zawierać DurableClient powiązanie wejściowe. Klient jest używany do uruchamiania aranżacji. Może również pomóc w zwracaniu odpowiedzi HTTP zawierającej adresy URL do sprawdzania stanu nowej aranżacji.
Użyj df.getClient polecenia , aby uzyskać DurableOrchestrationClient obiekt. Klient jest używany do uruchamiania aranżacji. Może również pomóc w zwracaniu odpowiedzi HTTP zawierającej adresy URL do sprawdzania stanu nowej aranżacji.
Aby zarządzać orkiestratorami i korzystać z niej, funkcja wymaga powiązania wejściowego durableClient . To powiązanie należy określić w argumencie extraInputs podczas rejestrowania funkcji. Dane durableClient wejściowe można uzyskać przez wywołanie metody df.input.durableClient().
Użyj df.getClient polecenia , aby uzyskać DurableClient obiekt. Klient jest używany do uruchamiania aranżacji. Może również pomóc w zwracaniu odpowiedzi HTTP zawierającej adresy URL do sprawdzania stanu nowej aranżacji.
Aby korzystać z orkiestratorów, funkcja musi zawierać durableClient powiązanie wejściowe.
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)
Użyj konstruktora, DurableOrchestrationClient aby uzyskać klienta Durable Functions. Klient jest używany do uruchamiania aranżacji. Może również pomóc w zwracaniu odpowiedzi HTTP zawierającej adresy URL do sprawdzania stanu nowej aranżacji.
Uruchamianie aplikacji przykładowej
Aby wykonać E1_HelloSequence orkiestrację, wyślij następujące żądanie HTTP POST do HttpStart funkcji.
POST http://{host}/orchestrators/E1_HelloSequence
Uwaga
Poprzedni fragment kodu HTTP zakłada, że w host.json pliku znajduje się wpis, który usuwa domyślny api/ prefiks ze wszystkich adresów URL funkcji wyzwalacza HTTP. Znaczniki dla tej konfiguracji można znaleźć w pliku w host.json przykładach.
Jeśli na przykład używasz przykładu w aplikacji funkcji o nazwie "myfunctionapp", zastąp ciąg "{host}" ciągiem "myfunctionapp.azurewebsites.net".
Wynikiem jest odpowiedź HTTP 202, taka jak ta (przycięta do zwięzłości):
W tym momencie orkiestracja jest w kolejce i zaczyna działać natychmiast. Adres URL w nagłówku Location może służyć do sprawdzania stanu wykonania.
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
Wynikiem jest stan aranżacji. Jest uruchamiana i wykonywana szybko, więc zobaczysz ją w stanie Ukończono z odpowiedzią, która wygląda następująco (przycięta do zwięzłości):
Jak widać, runtimeStatus element wystąpienia jest ukończony i output zawiera wynik serializacji JSON wykonania funkcji orkiestratora.
Uwaga
Podobną logikę początkową można zaimplementować dla innych typów wyzwalaczy, takich jak queueTrigger, lub eventHubTriggertimerTrigger.
Przyjrzyj się dziennikom wykonywania funkcji. Funkcja została uruchomiona E1_HelloSequence i ukończona wiele razy z powodu zachowania odtwarzania opisanego w temacie niezawodności orkiestracji . Z drugiej strony, było tylko trzy wykonania E1_SayHello , ponieważ te wykonania funkcji nie są odtwarzane.
Następne kroki
W tym przykładzie przedstawiono prostą aranżację łańcucha funkcji. W następnym przykładzie pokazano, jak zaimplementować wzorzec wentylatora/wentylatora.