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 DurableOrchestrationContext
IDurableOrchestrationContext
zamiast . 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 DurableOrchestrationContext
IDurableOrchestrationContext
zamiast . 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 DurableOrchestrationContext
IDurableOrchestrationContext
zamiast . 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 DurableOrchestrationClient
IDurableOrchestrationClient
zamiast . 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.