Condividi tramite


Gestione di eventi esterni in Funzioni permanenti (Funzioni di Azure)

Le funzioni di orchestrazione sono in grado di attendere e restare in ascolto di eventi esterni. Questa funzionalità di Funzioni permanenti è spesso utile per gestire l'interazione umana o altri trigger esterni.

Nota

Gli eventi esterni sono operazioni asincrone unidirezionali. Non sono adatti per situazioni in cui il client che invia l'evento necessita di una risposta sincrona da parte dell'agente di orchestrazione.

Attendere gli eventi

L'API "wait-for-external-event" dell'associazione di trigger di orchestrazione consente a una funzione dell'agente di orchestrazione di attendere e ascoltare in modo asincrono un evento recapitato da un client esterno. La funzione di orchestrazione in ascolto dichiara il nome dell'evento e la forma dei dati che si aspetta di ricevere.

[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
    }
}

Nota

Il codice C# precedente è per Durable Functions 2.x. Per Durable Functions 1.x, è necessario usare DurableOrchestrationContext anziché IDurableOrchestrationContext. Per altre informazioni sulle differenze tra le versioni, vedere l'articolo Versioni di Durable Functions.

Nell'esempio precedente è in attesa di un singolo evento specifico ed esegue l'azione quando lo riceve.

È possibile rimanere in ascolto di più eventi in modo simultaneo, come nell'esempio seguente, che è in attesa di una delle tre notifiche degli eventi possibili.

[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)
    {
        // ...
    }
}

Nota

Il codice C# precedente è per Durable Functions 2.x. Per Durable Functions 1.x, è necessario usare DurableOrchestrationContext anziché IDurableOrchestrationContext. Per altre informazioni sulle differenze tra le versioni, vedere l'articolo Versioni di Durable Functions.

Nell'esempio precedente è in ascolto di uno qualsiasi di più eventi. È anche possibile attendere tutti gli eventi.

[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);
}

Nota

Il codice precedente è per Durable Functions 2.x. Per Durable Functions 1.x, è necessario usare DurableOrchestrationContext anziché IDurableOrchestrationContext. Per altre informazioni sulle differenze tra le versioni, vedere l'articolo Versioni di Durable Functions.

In .NET se il payload dell'evento non può essere convertito nel tipo previsto T, viene generata un'eccezione.

L'API "wait-for-external-event" attende un tempo illimitato per alcuni input. È possibile scaricare l'app per le funzioni in modo sicuro durante l'attesa. Se e quando si riceve un evento per questa istanza di orchestrazione,l'app viene riattivata automaticamente ed elabora immediatamente l'evento.

Nota

Se l'app per le funzioni usa il piano a consumo, non vengono addebitati addebiti per la fatturazione mentre una funzione dell'agente di orchestrazione è in attesa di un'attività di evento esterno, indipendentemente dal tempo di attesa.

Come per Le funzioni di attività, gli eventi esterni hanno una garanzia di recapito at-least-once . Ciò significa che, in determinate condizioni (ad esempio riavvii, ridimensionamento, arresti anomali e così via), l'applicazione potrebbe ricevere duplicati dello stesso evento esterno. Pertanto, è consigliabile che gli eventi esterni contengano un tipo di ID che consenta di deduplicarli manualmente negli agenti di orchestrazione.

Inviare gli eventi

È possibile usare l'API "raise-event" definita dall'associazione client di orchestrazione per inviare un evento esterno a un'orchestrazione. È anche possibile usare l'API HTTP dell'evento di generazione predefinita per inviare un evento esterno a un'orchestrazione.

Un evento generato include un ID istanza, un eventName e eventData come parametri. Le funzioni dell'agente di orchestrazione gestiscono questi eventi usando le API "wait-for-external-event". EventName deve corrispondere sia all'invio che alla ricezione affinché l'evento venga elaborato. I dati dell'evento devono anche essere serializzabili in FORMATO JSON.

Internamente, i meccanismi "raise-event" accodare un messaggio che viene prelevato dalla funzione dell'agente di orchestrazione in attesa. Se l'istanza non è in attesa del nome dell'evento specificato, il messaggio di evento viene aggiunto a una coda in memoria. Se l'istanza di orchestrazione in seguito inizia l'ascolto per tale nome dell'evento, controllerà la presenza dei messaggi di evento nella coda.

Nota

Se non esiste alcuna istanza di orchestrazione con l'ID istanza specificato, il messaggio di evento viene rimosso.

Di seguito è riportata una funzione di esempio attivata da coda che invia un evento di "approvazione" a un'istanza della funzione dell'agente di orchestrazione. L'ID istanza di orchestrazione proviene dal corpo del messaggio in coda.

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

Nota

Il codice C# precedente è per Durable Functions 2.x. Per Durable Functions 1.x, è necessario usare OrchestrationClient l'attributo anziché l'attributo DurableClient ed è necessario usare il DurableOrchestrationClient tipo di IDurableOrchestrationClientparametro anziché . Per altre informazioni sulle differenze tra le versioni, vedere l'articolo Versioni di Durable Functions.

Internamente, l'API "raise-event" accoda un messaggio che viene prelevato dalla funzione dell'agente di orchestrazione in attesa. Se l'istanza non è in attesa del nome dell'evento specificato , il messaggio di evento viene aggiunto a un buffer in memoria. Se l'istanza di orchestrazione inizia successivamente ad ascoltare il nome dell'evento, verificherà il buffer per i messaggi di evento e attiverà l'attività in attesa.

Nota

Se non esiste alcuna istanza di orchestrazione con l'ID istanza specificato, il messaggio di evento viene rimosso.

HTTP

Di seguito è riportato un esempio di richiesta HTTP che genera un evento "Approvazione" a un'istanza di orchestrazione.

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

"true"

In questo caso, l'ID istanza è hardcoded come MyInstanceId.

Passaggi successivi