Agenti di orchestrazione singleton in Funzioni permanenti (Funzioni di Azure)

Per i processi in background, spesso è necessario assicurarsi che venga eseguita una sola istanza di un agente di orchestrazione specifico alla volta. È possibile garantire questo tipo di comportamento singleton in Durable Functions assegnando un ID istanza specifico a un agente di orchestrazione durante la creazione.

Esempio di singleton

L'esempio seguente mostra una funzione trigger HTTP che crea un'orchestrazione del processo in background singleton. Il codice garantisce l'esistenza di una sola istanza per un ID istanza specificato.

[FunctionName("HttpStartSingle")]
public static async Task<HttpResponseMessage> RunSingle(
    [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/{instanceId}")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient starter,
    string functionName,
    string instanceId,
    ILogger log)
{
    // Check if an instance with the specified ID already exists or an existing one stopped running(completed/failed/terminated).
    var existingInstance = await starter.GetStatusAsync(instanceId);
    if (existingInstance == null 
    || existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Completed 
    || existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Failed 
    || existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Terminated)
    {
        // An instance with the specified ID doesn't exist or an existing one stopped running, create one.
        dynamic eventData = await req.Content.ReadAsAsync<object>();
        await starter.StartNewAsync(functionName, instanceId, eventData);
        log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
        return starter.CreateCheckStatusResponse(req, instanceId);
    }
    else
    {
        // An instance with the specified ID exists or an existing one still running, don't create one.
        return new HttpResponseMessage(HttpStatusCode.Conflict)
        {
            Content = new StringContent($"An instance with ID '{instanceId}' already exists."),
        };
    }
}

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 parametro anziché IDurableOrchestrationClient. Per altre informazioni sulle differenze tra le versioni, vedere l'articolo Durable Functions versioni.

Per impostazione predefinita, gli ID delle istanze sono GUID generati in modo casuale. Nell'esempio precedente, tuttavia, l'ID istanza viene passato nei dati di route dall'URL. Il codice recupera quindi i metadati dell'istanza di orchestrazione per verificare se un'istanza con l'ID specificato è già in esecuzione. Se non è in esecuzione alcuna istanza di questo tipo, viene creata una nuova istanza con tale ID.

Nota

In questo esempio c'è una possibile race condition. Se due istanze di HttpStartSingle vengono eseguite contemporaneamente, entrambe le chiamate di funzione segnaleranno l'esito positivo, ma verrà effettivamente avviata solo un'istanza dell'orchestrazione. A seconda dei requisiti, questo potrebbe avere effetti indesiderati.

I dettagli di implementazione della funzione dell'agente di orchestrazione non sono effettivamente importanti. Può trattarsi di una funzione di agente di orchestrazione regolare che viene avviata e completata oppure può essere eseguita in modo permanente (si tratta di un'orchestrazione perenne). L'aspetto importante è che in esecuzione un'unica istanza alla volta.

Passaggi successivi