Share via


Singleton-orchestrators in Durable Functions (Azure Functions)

Voor achtergrondtaken moet u er vaak voor zorgen dat er slechts één exemplaar van een bepaalde orchestrator tegelijk wordt uitgevoerd. U kunt dit soort singletongedrag in Durable Functions controleren door een specifieke instantie-id toe te wijzen aan een orchestrator wanneer u deze maakt.

Singleton-voorbeeld

In het volgende voorbeeld ziet u een HTTP-triggerfunctie waarmee een singleton-achtergrondtaakindeling wordt gemaakt. De code zorgt ervoor dat er slechts één exemplaar bestaat voor een opgegeven exemplaar-id.

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

Notitie

De vorige C#-code is voor Durable Functions 2.x. Voor Durable Functions 1.x moet u het kenmerk gebruiken OrchestrationClient in plaats van het DurableClient kenmerk en moet u het DurableOrchestrationClient parametertype gebruiken in plaats van IDurableOrchestrationClient. Zie het artikel Durable Functions versies voor meer informatie over de verschillen tussen versies.

Instantie-id's zijn standaard willekeurig gegenereerde GUID's. In het vorige voorbeeld wordt de instantie-id echter doorgegeven in routegegevens van de URL. De code haalt vervolgens de metagegevens van het indelingsexemplaar op om te controleren of een exemplaar met de opgegeven id al wordt uitgevoerd. Als er geen dergelijk exemplaar wordt uitgevoerd, wordt er een nieuw exemplaar gemaakt met die id.

Notitie

Er is een mogelijke racevoorwaarde in dit voorbeeld. Als twee exemplaren van HttpStartSingle gelijktijdig worden uitgevoerd, melden beide functieaanroepen dat het is gelukt, maar wordt slechts één indelingsexemplaar daadwerkelijk gestart. Afhankelijk van uw behoeften kan dit ongewenste bijwerkingen hebben.

De implementatiedetails van de orchestratorfunctie zijn eigenlijk niet van belang. Het kan een reguliere orchestratorfunctie zijn die wordt gestart en voltooid, of een functie die voor altijd wordt uitgevoerd (dat wil gezegd, een eeuwige indeling). Het belangrijke punt is dat er maar één exemplaar tegelijk wordt uitgevoerd.

Volgende stappen