Udostępnij za pośrednictwem


Obsługa zdarzeń zewnętrznych w usłudze Durable Functions (Azure Functions)

Funkcje programu Orchestrator mają możliwość oczekiwania i nasłuchiwania zdarzeń zewnętrznych. Ta funkcja rozszerzenia Durable Functions jest często przydatna do obsługi interakcji człowieka lub innych wyzwalaczy zewnętrznych.

Uwaga

Zdarzenia zewnętrzne to jednokierunkowe operacje asynchroniczne. Nie są one odpowiednie w sytuacjach, w których klient wysyłający zdarzenie potrzebuje synchronicznej odpowiedzi z funkcji orkiestratora.

Czekaj na zdarzenia

Interfejs API "wait-for-external-event" powiązania wyzwalacza orkiestracji umożliwia asynchroniczne oczekiwanie i nasłuchiwanie zdarzenia dostarczonego przez klienta zewnętrznego. Funkcja orkiestratora nasłuchiwania deklaruje nazwę zdarzenia i kształt danych , które oczekuje do odebrania.

[FunctionName("BudgetApproval")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool approved = await context.WaitForExternalEvent<bool>("Approval");
    if (approved)
    {
        // approval granted - do the approved action
    }
    else
    {
        // approval denied - send a notification
    }
}

Uwaga

Poprzedni kod języka C# jest przeznaczony dla rozszerzenia Durable Functions 2.x. W przypadku rozszerzenia Durable Functions 1.x należy użyć funkcji DurableOrchestrationContextIDurableOrchestrationContextzamiast . Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł Wersje rozszerzenia Durable Functions.

Powyższy przykład nasłuchuje określonego pojedynczego zdarzenia i podejmuje działania po odebraniu.

Możesz nasłuchiwać wielu zdarzeń jednocześnie, na przykład w poniższym przykładzie, co czeka na jedno z trzech możliwych powiadomień o zdarzeniach.

[FunctionName("Select")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var event1 = context.WaitForExternalEvent<float>("Event1");
    var event2 = context.WaitForExternalEvent<bool>("Event2");
    var event3 = context.WaitForExternalEvent<int>("Event3");

    var winner = await Task.WhenAny(event1, event2, event3);
    if (winner == event1)
    {
        // ...
    }
    else if (winner == event2)
    {
        // ...
    }
    else if (winner == event3)
    {
        // ...
    }
}

Uwaga

Poprzedni kod języka C# jest przeznaczony dla rozszerzenia Durable Functions 2.x. W przypadku rozszerzenia Durable Functions 1.x należy użyć funkcji DurableOrchestrationContextIDurableOrchestrationContextzamiast . Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł Wersje rozszerzenia Durable Functions.

Poprzedni przykład nasłuchuje dowolnego z wielu zdarzeń. Istnieje również możliwość oczekiwania na wszystkie zdarzenia.

[FunctionName("NewBuildingPermit")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string applicationId = context.GetInput<string>();

    var gate1 = context.WaitForExternalEvent("CityPlanningApproval");
    var gate2 = context.WaitForExternalEvent("FireDeptApproval");
    var gate3 = context.WaitForExternalEvent("BuildingDeptApproval");

    // all three departments must grant approval before a permit can be issued
    await Task.WhenAll(gate1, gate2, gate3);

    await context.CallActivityAsync("IssueBuildingPermit", applicationId);
}

Uwaga

Poprzedni kod jest przeznaczony dla rozszerzenia Durable Functions 2.x. W przypadku rozszerzenia Durable Functions 1.x należy użyć funkcji DurableOrchestrationContextIDurableOrchestrationContextzamiast . Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł Wersje rozszerzenia Durable Functions.

Jeśli na platformie .NET nie można przekonwertować ładunku zdarzenia na oczekiwany typ T, zgłaszany jest wyjątek.

Interfejs API "wait-for-external-event" czeka przez czas nieokreślony na niektóre dane wejściowe. Aplikacja funkcji może zostać bezpiecznie zwolniona podczas oczekiwania. Jeśli i po nadejściu zdarzenia dla tego wystąpienia orkiestracji, jest ono automatycznie wybudzone i natychmiast przetwarza zdarzenie.

Uwaga

Jeśli aplikacja funkcji korzysta z planu zużycia, opłaty za rozliczenia są naliczane, gdy funkcja orkiestratora oczekuje na zadanie zdarzenia zewnętrznego, bez względu na czas oczekiwania.

Podobnie jak w przypadku funkcji działania, zdarzenia zewnętrzne mają co najmniej jednokrotną gwarancję dostarczania. Oznacza to, że w pewnych warunkach (takich jak ponowne uruchomienia, skalowanie, awarie itp.), aplikacja może odbierać duplikaty tego samego zdarzenia zewnętrznego. W związku z tym zaleca się, aby zdarzenia zewnętrzne zawierały jakiś identyfikator, który umożliwia ich ręczne deduplikowanie w orkiestratorach.

Wysyłanie zdarzeń

Możesz użyć interfejsu API "raise-event" zdefiniowanego przez powiązanie klienta orkiestracji, aby wysłać zdarzenie zewnętrzne do aranżacji. Możesz również użyć wbudowanego interfejsu API HTTP zdarzenia w celu wysłania zdarzenia zewnętrznego do aranżacji.

Zgłoszone zdarzenie zawiera identyfikator wystąpienia, eventName i eventData jako parametry. Funkcje programu Orchestrator obsługują te zdarzenia przy użyciu interfejsów API "wait-for-external-event". Nazwa zdarzenia musi być zgodna zarówno z końcem wysyłania, jak i odbierania w celu przetworzenia zdarzenia. Dane zdarzenia muszą również być serializowalne w formacie JSON.

Wewnętrznie mechanizmy "raise-event" w kolejce komunikat, który zostanie odebrany przez funkcję oczekującego orkiestratora. Jeśli wystąpienie nie oczekuje na określoną nazwę zdarzenia, komunikat zdarzenia zostanie dodany do kolejki w pamięci. Jeśli wystąpienie orkiestracji później zacznie nasłuchiwać tej nazwy zdarzenia, sprawdzi kolejkę komunikatów o zdarzeniach.

Uwaga

Jeśli nie ma wystąpienia orkiestracji z określonym identyfikatorem wystąpienia, komunikat zdarzenia zostanie odrzucony.

Poniżej znajduje się przykładowa funkcja wyzwalana przez kolejkę, która wysyła zdarzenie "Zatwierdzenie" do wystąpienia funkcji orkiestratora. Identyfikator wystąpienia orkiestracji pochodzi z treści komunikatu kolejki.

[FunctionName("ApprovalQueueProcessor")]
public static async Task Run(
    [QueueTrigger("approval-queue")] string instanceId,
    [DurableClient] IDurableOrchestrationClient client)
{
    await client.RaiseEventAsync(instanceId, "Approval", true);
}

Uwaga

Poprzedni kod języka C# jest przeznaczony dla rozszerzenia Durable Functions 2.x. W przypadku rozszerzenia Durable Functions 1.x należy użyć OrchestrationClient atrybutu zamiast atrybutu DurableClient i należy użyć typu parametru DurableOrchestrationClientIDurableOrchestrationClientzamiast . Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł Wersje rozszerzenia Durable Functions.

Wewnętrznie interfejs API "raise-event" kolejkuje komunikat, który jest odbierany przez funkcję oczekującą orkiestratora. Jeśli wystąpienie nie oczekuje na określoną nazwę zdarzenia, komunikat zdarzenia zostanie dodany do buforu w pamięci. Jeśli wystąpienie orkiestracji później rozpocznie nasłuchiwanie tej nazwy zdarzenia, sprawdzi bufor komunikatów o zdarzeniach i wyzwoli zadanie, które czekało na to.

Uwaga

Jeśli nie ma wystąpienia orkiestracji z określonym identyfikatorem wystąpienia, komunikat zdarzenia zostanie odrzucony.

HTTP

Poniżej przedstawiono przykład żądania HTTP, które zgłasza zdarzenie "Zatwierdzenie" do wystąpienia aranżacji.

POST /runtime/webhooks/durabletask/instances/MyInstanceId/raiseEvent/Approval&code=XXX
Content-Type: application/json

"true"

W takim przypadku identyfikator wystąpienia jest zakodowany jako MyInstanceId.

Następne kroki