Szybki start: tworzenie aplikacji Durable Functions JavaScript

Użyj Durable Functions, funkcji Azure Functions, aby napisać stanowe przepływy pracy bezserwerowe w języku JavaScript. W tym przewodniku Szybki start sklonujesz i uruchomisz przykładową aplikację, która demonstruje dwa typowe wzorce aranżacji:

  • Łańcuch funkcji: sekwencyjnie wywołuje działania (Tokio → Seattle → Londynie).
  • Fan-out/fan-in: Wywołuje działania równolegle w pięciu miastach, a następnie agreguje wyniki.

Pod koniec obie orkiestracje będą uruchomione lokalnie przy użyciu emulatora Durable Task Scheduler, a ich stan będzie można wyświetlić w panelu.

  • Sklonuj i przygotuj przykładowy projekt Hello Cities.
  • Skonfiguruj emulator narzędzia Durable Task Scheduler i Azurite na potrzeby programowania lokalnego.
  • Uruchom aplikację funkcji i uruchom obie aranżacje.
  • Przejrzyj stan orkiestracji i dane wyjściowe na pulpicie nawigacyjnym narzędzia Durable Task Scheduler.

Wymagania wstępne

Konfigurowanie emulatora harmonogramu zadań Durable Task Scheduler

Emulator harmonogramu zadań Durable udostępnia lokalne środowisko programistyczne, dzięki czemu można testować aranżacje bez subskrypcji Azure. Host usługi Functions wymaga również Azurite dla magazynu lokalnego.

Uruchom oba kontenery:

docker run -d --name dtsemulator -p 8080:8080 -p 8082:8082 \
  mcr.microsoft.com/dts/dts-emulator:latest

docker run -d --name azurite -p 10000:10000 -p 10001:10001 -p 10002:10002 \
  mcr.microsoft.com/azure-storage/azurite

Wskazówka

Po uruchomieniu emulatora możesz uzyskać dostęp do pulpitu nawigacyjnego narzędzia Durable Task Scheduler pod adresem , http://localhost:8082 aby monitorować aranżacje.

Uruchamianie przykładu szybkiego startu

  1. Przejdź do przykładowego katalogu Hello Cities:

    cd samples/durable-functions/javascript/HelloCities
    
  2. Instalacja zależności:

    npm install
    
  3. Sprawdź, czy local.settings.json plik zawiera następującą konfigurację:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "node",
        "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
      }
    }
    
  4. Uruchom aplikację funkcji:

    func start
    
  5. W osobnym terminalu wyzwól orkiestrację łańcucha funkcji :

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartChaining
    $response
    

    Odpowiedź zawiera adresy URL stanu wystąpienia orkiestracji. statusQueryGetUri Skopiuj wartość i uruchom ją, aby sprawdzić wynik:

    Invoke-RestMethod -Uri $response.statusQueryGetUri
    
  6. Uruchom orkiestrację fan-out/fan-in:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartFanOutFanIn
    Invoke-RestMethod -Uri $response.statusQueryGetUri
    

Oczekiwane dane wyjściowe

Żądanie POST zwraca odpowiedź w formacie JSON z adresami URL statusu. Przykład:

{
  "id": "<instanceId>",
  "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/<instanceId>?code=...",
  "sendEventPostUri": "...",
  "terminatePostUri": "...",
  "purgeHistoryDeleteUri": "..."
}

Gdy wykonasz zapytanie statusQueryGetUri, a element runtimeStatus aranżacji ma wartość Completed, wyniki powitania znajdziesz w polu output. Orkiestracja łańcuchowa zwraca:

{
  "name": "chainingOrchestration",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
}

Orkiestracja typu fan-out/fan-in zwraca:

{
  "name": "fanOutFanInOrchestration",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!", "Hello Paris!", "Hello Berlin!"]
}

Wskazówka

Jeśli runtimeStatus wyświetla Running lub Pending, zaczekaj chwilę i ponownie odpytaj statusQueryGetUri.

Otwórz pulpit nawigacyjny Durable Task Scheduler pod adresem http://localhost:8082, aby wyświetlić stan orkiestracji i historię wykonania.

Omówienie kodu

W przykładzie użyto modelu programowania Node.js w wersji 4, w którym wszystkie funkcje są definiowane w jednym pliku (src/functions/helloCities.js).

Funkcja aktywności

Działanie sayHello przyjmuje nazwę miasta i zwraca powitanie:

df.app.activity("sayHello", {
  handler: (city) => {
    return `Hello ${city}!`;
  },
});

Funkcje programu Orchestrator

Orkiestrator łańcuchowy wywołuje sayHello sekwencyjnie dla trzech miast:

df.app.orchestration("chainingOrchestration", function* (context) {
  const outputs = [];
  outputs.push(yield context.df.callActivity("sayHello", "Tokyo"));
  outputs.push(yield context.df.callActivity("sayHello", "Seattle"));
  outputs.push(yield context.df.callActivity("sayHello", "London"));
  return outputs;
});

Orkiestrator fan-out/fan-in planuje równolegle działania:

df.app.orchestration("fanOutFanInOrchestration", function* (context) {
  const cities = ["Tokyo", "Seattle", "London", "Paris", "Berlin"];

  // Fan-out: schedule all activities in parallel
  const tasks = cities.map((city) => context.df.callActivity("sayHello", city));

  // Fan-in: wait for all to complete
  const results = yield context.df.Task.all(tasks);
  return results;
});

Funkcje klienta

Funkcje klienta wyzwalane przez protokół HTTP uruchamiają każdą aranżację. Na przykład inicjator łańcuchowania:

app.http("StartChaining", {
  route: "StartChaining",
  methods: ["POST"],
  authLevel: "anonymous",
  extraInputs: [df.input.durableClient()],
  handler: async (request, context) => {
    const client = df.getClient(context);
    const instanceId = await client.startNew("chainingOrchestration");
    context.log(`Started chaining orchestration with ID = '${instanceId}'.`);
    return client.createCheckStatusResponse(request, instanceId);
  },
});

Konfiguracja

W przykładzie użyto emulatora Durable Task Scheduler jako magazynu danych. Jest to skonfigurowane w programie host.json:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.Core": "Warning"
    }
  },
  "extensions": {
    "durableTask": {
      "hubName": "default",
      "storageProvider": {
        "type": "azureManaged",
        "connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Uprzątnij zasoby

Zatrzymaj kontenery emulatora, gdy skończysz:

docker stop dtsemulator azurite && docker rm dtsemulator azurite

Następne kroki