Łączenie łańcuchów funkcji w rozszerzeniu Durable Functions — przykładowa sekwencja Hello
Artykuł
Łączenie funkcji odnosi się do wzorca wykonywania sekwencji funkcji w określonej kolejności. Często dane wyjściowe jednej funkcji należy zastosować do danych wejściowych innej funkcji. W tym artykule opisano sekwencję łańcucha utworzoną po ukończeniu przewodnika Szybki start rozszerzenia Durable Functions (C#, JavaScript, TypeScript, Python, PowerShell lub Java). Aby uzyskać więcej informacji na temat rozszerzenia Durable Functions, zobacz Durable Functions overview (Omówienie rozszerzenia Durable Functions).
Wersja 4 modelu programowania Node.js dla usługi 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ęzyków JavaScript i TypeScript. Dowiedz się więcej o różnicach między wersjami 3 i v4 w przewodniku migracji.
W poniższych fragmentach kodu javaScript (PM4) oznacza model programowania W wersji 4, nowe środowisko.
Funkcje
W tym artykule opisano 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 "Hello".
HttpStart: Funkcja klienta trwałego 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. Wartość zwracana każdego wywołania jest dodawana do outputs listy, która jest zwracana na końcu funkcji.
function.json
Jeśli do programowania używasz programu Visual Studio Code lub witryny Azure Portal, oto zawartość pliku function.json dla funkcji orkiestratora. Większość plików function.json orkiestratora 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 rozszerzenia Durable Functions w języku JavaScript. Istnieją trzy znaczące różnice między funkcją orkiestratora a innymi funkcjami języka JavaScript:
Funkcja jest owinięta w wywołaniu metody modułu durable-functionsorchestrator (tutaj ).df
Funkcja musi być synchroniczna. Ponieważ metoda "orchestrator" obsługuje ostateczne wywołanie "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 async. Wartość zwracana 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 rozszerzenia 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 zwracać.
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 async. Wartość zwracana każdego wywołania jest dodawana do outputs tablicy, która jest zwracana na końcu funkcji.
Uwaga
Rozszerzenie Durable Functions języka Python jest dostępne tylko dla środowiska uruchomieniowego usługi Functions 3.0.
function.json
Jeśli do programowania używasz programu Visual Studio Code lub witryny Azure Portal, oto zawartość pliku function.json dla funkcji orkiestratora. Większość plików function.json orkiestratora 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 rozszerzenia 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 koordynatora, stwierdzając main = df.Orchestrator.create(<orchestrator function name>) na końcu pliku. Ułatwia to odróżnienie go od innych, pomocnika, 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 async. Zwracana wartość każdego wywołania 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 podanej IDurableActivityContext opcji, aby wykonać akcje związane z działaniem, takie jak uzyskiwanie dostępu do wartości wejściowej przy użyciu polecenia GetInput<T>.
Implementacja E1_SayHello jest stosunkowo trywialną operacją 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 działania jest podobny do tego, z E1_HelloSequence tą różnicą, ż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.
Implementacja E1_SayHello jest stosunkowo trywialną operacją 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 przez funkcję orkiestratora znajdują się w context.bindings obiekcie pod nazwą activityTrigger powiązania — w tym przypadku context.bindings.name. Nazwę powiązania można ustawić jako parametr wyeksportowanej funkcji i uzyskać do nich bezpośredni dostęp, czyli przykładowy kod.
Implementacja sayHello jest stosunkowo trywialną operacją 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 działania jest podobny do tego, z E1_HelloSequence tą różnicą, ż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.
Funkcja klienta HttpStart
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 wchodzić w interakcje z orkiestratorami, funkcja musi zawierać DurableClient powiązanie wejściowe. Aby rozpocząć aranżację, należy użyć klienta. Może również pomóc zwrócić odpowiedź HTTP zawierającą adresy URL w celu sprawdzenia stanu nowej aranżacji.
Użyj df.getClient polecenia , aby uzyskać DurableOrchestrationClient obiekt. Aby rozpocząć aranżację, należy użyć klienta. Może również pomóc zwrócić odpowiedź HTTP zawierającą adresy URL w celu sprawdzenia 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. Aby rozpocząć aranżację, należy użyć klienta. Może również pomóc zwrócić odpowiedź HTTP zawierającą adresy URL w celu sprawdzenia stanu nowej aranżacji.
Aby wchodzić w interakcje z orkiestratorami, 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. Aby rozpocząć aranżację, należy użyć klienta. Może również pomóc zwrócić odpowiedź HTTP zawierającą adresy URL w celu sprawdzenia stanu nowej aranżacji.
Uruchamianie aplikacji przykładowej
Aby wykonać aranżację E1_HelloSequence , 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 orkiestracji. Jest uruchamiany i wykonywany szybko, więc zobaczysz go w stanie Ukończono z odpowiedzią, która wygląda następująco (przycięte do zwięzłości):
Jak widać, wystąpienie runtimeStatus jest ukończone i output zawiera wynik serializacji JSON wykonywania funkcji orkiestratora.
Uwaga
Możesz zaimplementować podobną logikę startową dla innych typów wyzwalaczy, takich jak queueTrigger, eventHubTriggerlub timerTrigger.
Przyjrzyj się dziennikom wykonywania funkcji. Funkcja została uruchomiona E1_HelloSequence i ukończona wiele razy ze względu na zachowanie odtwarzania opisane w temacie niezawodność orkiestracji. Z drugiej strony były tylko trzy wykonania, ponieważ te wykonania E1_SayHello 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 fan-out/fan-in.