Wat is Durable Functions?What are Durable Functions?

Durable functions is een uitbrei ding van Azure functions waarmee stateful functies kunnen worden geschreven in een serverloze reken omgeving.Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless compute environment. Met de uitbrei ding kunt u stateful werk stromen definiëren door Orchestrator-functies en stateful-entiteiten te schrijven door entiteits functies te schrijven met behulp van het Azure functions-programmeer model.The extension lets you define stateful workflows by writing orchestrator functions and stateful entities by writing entity functions using the Azure Functions programming model. Achter de schermen beheert de uitbrei ding status, controle punten en wordt de computer opnieuw opgestart, zodat u zich kunt concentreren op uw bedrijfs logica.Behind the scenes, the extension manages state, checkpoints, and restarts for you, allowing you to focus on your business logic.

Ondersteunde talenSupported languages

Durable Functions ondersteunt momenteel de volgende talen:Durable Functions currently supports the following languages:

  • C# : zowel vooraf gecompileerde klassebibliotheken als C#-script.C#: both precompiled class libraries and C# script.
  • F# : vooraf gecompileerde klassebibliotheken en F#-script.F#: precompiled class libraries and F# script. F#-script wordt alleen ondersteund voor versie 1.x van de Azure Functions-runtime.F# script is only supported for version 1.x of the Azure Functions runtime.
  • JavaScript: alleen ondersteund voor versie 2.x van de Azure Functions-runtime.JavaScript: supported only for version 2.x of the Azure Functions runtime. Versie 1.7.0 of hoger van de Durable Functions-extensie vereist.Requires version 1.7.0 of the Durable Functions extension, or a later version.

Durable Functions heeft als doel alle Azure Functions-talen te ondersteunen.Durable Functions has a goal of supporting all Azure Functions languages. Zie Durable Functions issues list voor de laatste voortgangsstatus van de ondersteuning voor meer talen.See the Durable Functions issues list for the latest status of work to support additional languages.

Net als Azure Functions zijn er sjablonen waarmee u Durable Functions kunt ontwikkelen met behulp van Visual studio 2019, Visual Studio Codeen de Azure Portal.Like Azure Functions, there are templates to help you develop Durable Functions using Visual Studio 2019, Visual Studio Code, and the Azure portal.

ToepassingspatronenApplication patterns

De primaire use case voor Durable Functions is het vereenvoudigen van complexe stateful coördinatievereisten in serverloze toepassingen.The primary use case for Durable Functions is simplifying complex, stateful coordination requirements in serverless applications. In de volgende secties worden typische toepassings patronen beschreven die kunnen profiteren van Durable Functions:The following sections describe typical application patterns that can benefit from Durable Functions:

Patroon #1: FunctiekoppelingPattern #1: Function chaining

In het patroon functie koppeling wordt een reeks functies in een specifieke volg orde uitgevoerd.In the function chaining pattern, a sequence of functions executes in a specific order. In dit patroon wordt de uitvoer van een functie toegepast op de invoer van een andere functie.In this pattern, the output of one function is applied to the input of another function.

Een diagram van het patroon van de functie koppeling

U kunt Durable Functions gebruiken om het patroon van de functie koppeling beknopt te implementeren, zoals wordt weer gegeven in het volgende voor beeld:You can use Durable Functions to implement the function chaining pattern concisely as shown in the following example:

C#C#

[FunctionName("Chaining")]
public static async Task<object> Run(
    [OrchestrationTrigger] DurableOrchestrationContext context)
{
    try
    {
        var x = await context.CallActivityAsync<object>("F1");
        var y = await context.CallActivityAsync<object>("F2", x);
        var z = await context.CallActivityAsync<object>("F3", y);
        return  await context.CallActivityAsync<object>("F4", z);
    }
    catch (Exception)
    {
        // Error handling or compensation goes here.
    }
}

Java script (alleen functies 2. x)JavaScript (Functions 2.x only)

const df = require("durable-functions");

module.exports = df.orchestrator(function*(context) {
    const x = yield context.df.callActivity("F1");
    const y = yield context.df.callActivity("F2", x);
    const z = yield context.df.callActivity("F3", y);
    return    yield context.df.callActivity("F4", z);
});

In dit voor beeld zijn de F1waarden F2 F3,, en F4 de namen van andere functies in de functie-app.In this example, the values F1, F2, F3, and F4 are the names of other functions in the function app. U kunt de controle stroom implementeren met behulp van normale verplichte coderings constructies.You can implement control flow by using normal imperative coding constructs. Code wordt van boven naar beneden uitgevoerd.Code executes from the top down. De code kan bestaan uit de bestaande semantiek van de taal besturings flow, zoals voor waarden en lussen.The code can involve existing language control flow semantics, like conditionals and loops. U kunt de logica voor fout afhandeling try in / / catch finally blokken toevoegen.You can include error handling logic in try/catch/finally blocks.

U kunt de context para meter [DurableOrchestrationContext] (.net) en het context.df object (Java script) gebruiken om andere functies aan te roepen op naam, para meters door geven en retour uitvoer.You can use the context parameter [DurableOrchestrationContext] (.NET) and the context.df object (JavaScript) to invoke other functions by name, pass parameters, and return function output. Telkens wanneer de code await aanroeptC#() yield of (Java script), wordt in het Durable functions Framework de voortgang van het huidige functie-exemplaar gecontroleerd.Each time the code calls await (C#) or yield (JavaScript), the Durable Functions framework checkpoints the progress of the current function instance. Als het proces of de virtuele machine halverwege de uitvoering wordt gerecycled, wordt het functie-exemplaar hervat await vanuit yield de voor gaande of-aanroep.If the process or VM recycles midway through the execution, the function instance resumes from the preceding await or yield call. Zie voor meer informatie de volgende sectie, patroon #2: Uitwaaieren/inwaaieren in.For more information, see the next section, Pattern #2: Fan out/fan in.

Notitie

Het context object in Java script vertegenwoordigt de volledige functie context, niet alleen de para meter [DurableOrchestrationContext].The context object in JavaScript represents the entire function context, not only the [DurableOrchestrationContext] parameter.

Patroon #2: Uitwaaieren/ventilator inPattern #2: Fan out/fan in

In het patroon uitwaaieren/ventilatoren voert u meerdere functies parallel uit en wacht u totdat alle functies zijn voltooid.In the fan out/fan in pattern, you execute multiple functions in parallel and then wait for all functions to finish. Vaak wordt een samen voeging uitgevoerd op de resultaten die worden geretourneerd door de functies.Often, some aggregation work is done on the results that are returned from the functions.

Een diagram van het uitwaaieren/ventilator patroon

Met normale functies kunt u uitwaaieren door de functie meerdere berichten naar een wachtrij te verzenden.With normal functions, you can fan out by having the function send multiple messages to a queue. Fanning weer in is veel lastiger.Fanning back in is much more challenging. Als u in een normale functie wilt inwaaieren, schrijft u code om bij te houden wanneer de functies die door de wachtrij worden geactiveerd, eindigen en vervolgens de functie-uitvoer op te slaan.To fan in, in a normal function, you write code to track when the queue-triggered functions end, and then store function outputs.

Met de extensie Durable Functions wordt dit patroon afgehandeld met relatief eenvoudige code:The Durable Functions extension handles this pattern with relatively simple code:

C#C#

[FunctionName("FanOutFanIn")]
public static async Task Run(
    [OrchestrationTrigger] DurableOrchestrationContext context)
{
    var parallelTasks = new List<Task<int>>();

    // Get a list of N work items to process in parallel.
    object[] workBatch = await context.CallActivityAsync<object[]>("F1");
    for (int i = 0; i < workBatch.Length; i++)
    {
        Task<int> task = context.CallActivityAsync<int>("F2", workBatch[i]);
        parallelTasks.Add(task);
    }

    await Task.WhenAll(parallelTasks);

    // Aggregate all N outputs and send the result to F3.
    int sum = parallelTasks.Sum(t => t.Result);
    await context.CallActivityAsync("F3", sum);
}

Java script (alleen functies 2. x)JavaScript (Functions 2.x only)

const df = require("durable-functions");

module.exports = df.orchestrator(function*(context) {
    const parallelTasks = [];

    // Get a list of N work items to process in parallel.
    const workBatch = yield context.df.callActivity("F1");
    for (let i = 0; i < workBatch.length; i++) {
        parallelTasks.push(context.df.callActivity("F2", workBatch[i]));
    }

    yield context.df.Task.all(parallelTasks);

    // Aggregate all N outputs and send the result to F3.
    const sum = parallelTasks.reduce((prev, curr) => prev + curr, 0);
    yield context.df.callActivity("F3", sum);
});

Het werk van de ventilator wordt gedistribueerd naar meerdere exemplaren F2 van de functie.The fan-out work is distributed to multiple instances of the F2 function. Het werk wordt bijgehouden met behulp van een dynamische lijst met taken.The work is tracked by using a dynamic list of tasks. De .net Task.WhenAll API of Java context.df.Task.all script-API wordt aangeroepen, zodat wordt gewacht tot alle aangeroepen functies zijn voltooid.The .NET Task.WhenAll API or JavaScript context.df.Task.all API is called, to wait for all the called functions to finish. Vervolgens worden de F2 functie-uitvoer geaggregeerd van de lijst met dynamische taken en door gegeven aan de F3 functie.Then, the F2 function outputs are aggregated from the dynamic task list and passed to the F3 function.

De automatische controle punten die zich voordoen await bij yield of aanroepen context.df.Task.all Task.WhenAll of ervoor zorgen dat een mogelijke Midway-crash of opnieuw opstarten niet nodig is om een reeds voltooide taak opnieuw te starten.The automatic checkpointing that happens at the await or yield call on Task.WhenAll or context.df.Task.all ensures that a potential midway crash or reboot doesn't require restarting an already completed task.

Notitie

In zeldzame gevallen is het mogelijk dat er een crash in het venster kan optreden nadat een activiteit functie is voltooid, maar voordat de voltooiing wordt opgeslagen in de Orchestration-geschiedenis.In rare circumstances, it's possible that a crash could happen in the window after an activity function completes but before its completion is saved into the orchestration history. Als dit gebeurt, wordt de activiteit functie opnieuw uitgevoerd vanaf het begin nadat het proces is hersteld.If this happens, the activity function would re-run from the beginning after the process recovers.

Patroon #3: Asynchrone HTTP-Api'sPattern #3: Async HTTP APIs

Het asynchrone HTTP API-patroon is een oplossing voor het probleem van het coördineren van de status van langlopende bewerkingen met externe clients.The async HTTP API pattern addresses the problem of coordinating the state of long-running operations with external clients. Een veelvoorkomende manier om dit patroon te implementeren, is door een HTTP-eind punt te laten activeren van de langlopende actie.A common way to implement this pattern is by having an HTTP endpoint trigger the long-running action. Leid vervolgens de client om naar een status eindpunt dat de client navraagt om te leren wanneer de bewerking is voltooid.Then, redirect the client to a status endpoint that the client polls to learn when the operation is finished.

Een diagram van het HTTP API-patroon

Durable Functions biedt ingebouwde ondersteuning voor dit patroon, waardoor de code die u moet schrijven om te communiceren met langlopende functie-uitvoeringen, wordt vereenvoudigd of verwijderd.Durable Functions provides built-in support for this pattern, simplifying or even removing the code you need to write to interact with long-running function executions. De Durable Functions Quick start-voor beelden (C# en Java script) tonen bijvoorbeeld een eenvoudige rest-opdracht die u kunt gebruiken om nieuwe Orchestrator-functie instanties te starten.For example, the Durable Functions quickstart samples (C# and JavaScript) show a simple REST command that you can use to start new orchestrator function instances. Nadat een exemplaar is gestart, worden de HTTP-Api's van de webhook met de status van de Orchestrator-functie weer gegeven.After an instance starts, the extension exposes webhook HTTP APIs that query the orchestrator function status.

In het volgende voor beeld worden REST-opdrachten weer gegeven die een Orchestrator starten en de status ervan opvragen.The following example shows REST commands that start an orchestrator and query its status. Voor de duidelijkheid worden bepaalde protocol gegevens uit het voor beeld wegge laten.For clarity, some protocol details are omitted from the example.

> curl -X POST https://myfunc.azurewebsites.net/orchestrators/DoWork -H "Content-Length: 0" -i
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec

{"id":"b79baf67f717453ca9e86c5da21e03ec", ...}

> curl https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec -i
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec

{"runtimeStatus":"Running","lastUpdatedTime":"2019-03-16T21:20:47Z", ...}

> curl https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec -i
HTTP/1.1 200 OK
Content-Length: 175
Content-Type: application/json

{"runtimeStatus":"Completed","lastUpdatedTime":"2019-03-16T21:20:57Z", ...}

Omdat de Durable Functions runtime de status voor u beheert, hoeft u uw eigen status tracking-mechanisme niet te implementeren.Because the Durable Functions runtime manages state for you, you don't need to implement your own status-tracking mechanism.

De uitbrei ding Durable Functions maakt ingebouwde HTTP-Api's beschikbaar waarmee langlopende integraties worden beheerd.The Durable Functions extension exposes built-in HTTP APIs that manage long-running orchestrations. U kunt dit patroon ook zelf implementeren door gebruik te maken van uw eigen functie Triggers (zoals HTTP, een wachtrij of Azure Event Hubs) en de Orchestration client-binding.You can alternatively implement this pattern yourself by using your own function triggers (such as HTTP, a queue, or Azure Event Hubs) and the orchestration client binding. U kunt bijvoorbeeld een wachtrij bericht gebruiken om beëindiging te activeren.For example, you might use a queue message to trigger termination. U kunt ook een HTTP-trigger gebruiken die wordt beveiligd met een Azure Active Directory verificatie beleid in plaats van de ingebouwde HTTP-Api's die een gegenereerde sleutel voor verificatie gebruiken.Or, you might use an HTTP trigger that's protected by an Azure Active Directory authentication policy instead of the built-in HTTP APIs that use a generated key for authentication.

Zie het artikel http-functies voor meer informatie. hierin wordt uitgelegd hoe u asynchrone, langlopende processen via http kunt weer geven met behulp van de extensie Durable functions.For more information, see the HTTP features article, which explains how you can expose asynchronous, long-running processes over HTTP using the Durable Functions extension.

Patroon #4: ControlerenPattern #4: Monitor

Het monitor patroon verwijst naar een flexibel, terugkerend proces in een werk stroom.The monitor pattern refers to a flexible, recurring process in a workflow. Een voor beeld is een polling totdat aan bepaalde voor waarden wordt voldaan.An example is polling until specific conditions are met. U kunt een normale Timer trigger gebruiken om een basis scenario te verhelpen, zoals een periodieke opschoon taak, maar het bijbehorende interval is statisch en het beheren van de levens duur van het exemplaar wordt complex.You can use a regular timer trigger to address a basic scenario, such as a periodic cleanup job, but its interval is static and managing instance lifetimes becomes complex. U kunt Durable Functions gebruiken voor het maken van flexibele terugkeer intervallen, het beheren van de levens duur van taken en het maken van meerdere monitor processen vanuit één indeling.You can use Durable Functions to create flexible recurrence intervals, manage task lifetimes, and create multiple monitor processes from a single orchestration.

Een voor beeld van het monitor patroon is het terugdraaien van het eerdere async HTTP API-scenario.An example of the monitor pattern is to reverse the earlier async HTTP API scenario. In plaats van een eind punt weer te geven voor een externe client om een langlopende bewerking te bewaken, gebruikt de langlopende monitor een extern eind punt en wordt er gewacht op een status wijziging.Instead of exposing an endpoint for an external client to monitor a long-running operation, the long-running monitor consumes an external endpoint, and then waits for a state change.

Een diagram van het monitor patroon

In een paar regels code kunt u Durable Functions gebruiken om meerdere monitors te maken die wille keurige eind punten observeren.In a few lines of code, you can use Durable Functions to create multiple monitors that observe arbitrary endpoints. De monitors kunnen de uitvoering beëindigen wanneer aan een voor waarde wordt voldaan, of de DurableOrchestrationClient kan de monitors beëindigen.The monitors can end execution when a condition is met, or the DurableOrchestrationClient can terminate the monitors. U kunt het interval van wait een monitor wijzigen op basis van een specifieke voor waarde (bijvoorbeeld exponentiële uitstel.)You can change a monitor's wait interval based on a specific condition (for example, exponential backoff.)

Met de volgende code wordt een basis monitor geïmplementeerd:The following code implements a basic monitor:

C#C#

[FunctionName("MonitorJobStatus")]
public static async Task Run(
    [OrchestrationTrigger] DurableOrchestrationContext context)
{
    int jobId = context.GetInput<int>();
    int pollingInterval = GetPollingInterval();
    DateTime expiryTime = GetExpiryTime();

    while (context.CurrentUtcDateTime < expiryTime)
    {
        var jobStatus = await context.CallActivityAsync<string>("GetJobStatus", jobId);
        if (jobStatus == "Completed")
        {
            // Perform an action when a condition is met.
            await context.CallActivityAsync("SendAlert", machineId);
            break;
        }

        // Orchestration sleeps until this time.
        var nextCheck = context.CurrentUtcDateTime.AddSeconds(pollingInterval);
        await context.CreateTimer(nextCheck, CancellationToken.None);
    }

    // Perform more work here, or let the orchestration end.
}

Java script (alleen functies 2. x)JavaScript (Functions 2.x only)

const df = require("durable-functions");
const moment = require("moment");

module.exports = df.orchestrator(function*(context) {
    const jobId = context.df.getInput();
    const pollingInternal = getPollingInterval();
    const expiryTime = getExpiryTime();

    while (moment.utc(context.df.currentUtcDateTime).isBefore(expiryTime)) {
        const jobStatus = yield context.df.callActivity("GetJobStatus", jobId);
        if (jobStatus === "Completed") {
            // Perform an action when a condition is met.
            yield context.df.callActivity("SendAlert", machineId);
            break;
        }

        // Orchestration sleeps until this time.
        const nextCheck = moment.utc(context.df.currentUtcDateTime).add(pollingInterval, 's');
        yield context.df.createTimer(nextCheck.toDate());
    }

    // Perform more work here, or let the orchestration end.
});

Wanneer een aanvraag wordt ontvangen, wordt er een nieuw Orchestration-exemplaar gemaakt voor die taak-ID.When a request is received, a new orchestration instance is created for that job ID. Het exemplaar pollt een status totdat aan een voor waarde wordt voldaan en de lus wordt afgesloten.The instance polls a status until a condition is met and the loop is exited. Een duurzame timer bepaalt het polling-interval.A durable timer controls the polling interval. Vervolgens kan er meer werk worden uitgevoerd of kan de indeling worden beëindigd.Then, more work can be performed, or the orchestration can end. Wanneer de context.CurrentUtcDateTime (.net) of context.df.currentUtcDateTime (Java script) de expiryTime waarde overschrijdt, wordt de monitor beëindigd.When the context.CurrentUtcDateTime (.NET) or context.df.currentUtcDateTime (JavaScript) exceeds the expiryTime value, the monitor ends.

Patroon #5: Menselijke tussenkomstPattern #5: Human interaction

Veel geautomatiseerde processen omvatten een soort Human interactie.Many automated processes involve some kind of human interaction. Mensen met een geautomatiseerd proces kunnen lastig zijn omdat ze niet als Maxi maal beschikbaar zijn en als reactie van Cloud Services.Involving humans in an automated process is tricky because people aren't as highly available and as responsive as cloud services. Een geautomatiseerd proces kan deze interactie toestaan door gebruik te maken van time-outs en compensatie logica.An automated process might allow for this interaction by using timeouts and compensation logic.

Een goedkeurings proces is een voor beeld van een bedrijfs proces waarbij menselijke interactie betrokken is.An approval process is an example of a business process that involves human interaction. Goed keuring van een manager kan vereist zijn voor een onkosten rapport dat een bepaald bedrag in Euro's overschrijdt.Approval from a manager might be required for an expense report that exceeds a certain dollar amount. Als het onkosten rapport binnen 72 uur niet door de Manager wordt goedgekeurd (misschien is de Manager op vakantie gezet), wordt een escalatie proces uitgevoerd om de goed keuring van iemand anders (mogelijk de Manager van de Manager) te verkrijgen.If the manager doesn't approve the expense report within 72 hours (maybe the manager went on vacation), an escalation process kicks in to get the approval from someone else (perhaps the manager's manager).

Een diagram van het menselijke interactie patroon

U kunt het patroon in dit voor beeld implementeren met behulp van een Orchestrator-functie.You can implement the pattern in this example by using an orchestrator function. De Orchestrator gebruikt een duurzame timer om goed keuring aan te vragen.The orchestrator uses a durable timer to request approval. De Orchestrator escaleren als er een time-out optreedt.The orchestrator escalates if timeout occurs. De Orchestrator wacht op een externe gebeurtenis, zoals een melding die wordt gegenereerd door een menselijke interactie.The orchestrator waits for an external event, such as a notification that's generated by a human interaction.

In deze voor beelden wordt een goedkeurings proces voor het voor beeld van het menselijke interactie patroon gemaakt:These examples create an approval process to demonstrate the human interaction pattern:

C#C#

[FunctionName("ApprovalWorkflow")]
public static async Task Run(
    [OrchestrationTrigger] DurableOrchestrationContext context)
{
    await context.CallActivityAsync("RequestApproval");
    using (var timeoutCts = new CancellationTokenSource())
    {
        DateTime dueTime = context.CurrentUtcDateTime.AddHours(72);
        Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token);

        Task<bool> approvalEvent = context.WaitForExternalEvent<bool>("ApprovalEvent");
        if (approvalEvent == await Task.WhenAny(approvalEvent, durableTimeout))
        {
            timeoutCts.Cancel();
            await context.CallActivityAsync("ProcessApproval", approvalEvent.Result);
        }
        else
        {
            await context.CallActivityAsync("Escalate");
        }
    }
}

Java script (alleen functies 2. x)JavaScript (Functions 2.x only)

const df = require("durable-functions");
const moment = require('moment');

module.exports = df.orchestrator(function*(context) {
    yield context.df.callActivity("RequestApproval");

    const dueTime = moment.utc(context.df.currentUtcDateTime).add(72, 'h');
    const durableTimeout = context.df.createTimer(dueTime.toDate());

    const approvalEvent = context.df.waitForExternalEvent("ApprovalEvent");
    if (approvalEvent === yield context.df.Task.any([approvalEvent, durableTimeout])) {
        durableTimeout.cancel();
        yield context.df.callActivity("ProcessApproval", approvalEvent.result);
    } else {
        yield context.df.callActivity("Escalate");
    }
});

Voor het maken van de duurzame timer context.CreateTimer , aanroep (.net context.df.createTimer ) of (Java script).To create the durable timer, call context.CreateTimer (.NET) or context.df.createTimer (JavaScript). De melding wordt ontvangen door context.WaitForExternalEvent (.net) of context.df.waitForExternalEvent (Java script).The notification is received by context.WaitForExternalEvent (.NET) or context.df.waitForExternalEvent (JavaScript). context.df.Task.any Vervolgens wordt Task.WhenAny (.net) of (Java script) aangeroepen om te bepalen of er eerst een time-out optreedt of de goed keuring verwerken (de goed keuring wordt ontvangen vóór de time-out).Then, Task.WhenAny (.NET) or context.df.Task.any (JavaScript) is called to decide whether to escalate (timeout happens first) or process the approval (the approval is received before timeout).

Een externe client kan de gebeurtenis melding verzenden naar een wacht functie die gebruikmaakt van de ingebouwde http-api's of met behulp van de DurableOrchestrationClient. RaiseEventAsync -API van een andere functie:An external client can deliver the event notification to a waiting orchestrator function by using either the built-in HTTP APIs or by using the DurableOrchestrationClient.RaiseEventAsync API from another function:

[FunctionName("RaiseEventToOrchestration")]
public static async Task Run(
    [HttpTrigger] string instanceId,
    [OrchestrationClient] DurableOrchestrationClient client)
{
    bool isApproved = true;
    await client.RaiseEventAsync(instanceId, "ApprovalEvent", isApproved);
}
const df = require("durable-functions");

module.exports = async function (context) {
    const client = df.getClient(context);
    const isApproved = true;
    await client.raiseEvent(instanceId, "ApprovalEvent", isApproved);
};
curl -d "true" http://localhost:7071/runtime/webhooks/durabletask/instances/{instanceId}/raiseEvent/ApprovalEvent -H "Content-Type: application/json"

Patroon #6: Aggregator (preview-versie)Pattern #6: Aggregator (preview)

Het zesde patroon is het verzamelen van gebeurtenis gegevens over een bepaalde periode in een enkele, adresseer bare entiteit.The sixth pattern is about aggregating event data over a period of time into a single, addressable entity. In dit patroon kunnen de gegevens die worden geaggregeerd afkomstig zijn uit meerdere bronnen, worden geleverd in batches of kunnen ze over een lange periode worden verspreid.In this pattern, the data being aggregated may come from multiple sources, may be delivered in batches, or may be scattered over long-periods of time. De aggregator moet mogelijk actie ondernemen op gebeurtenis gegevens terwijl deze arriveert, en externe clients moeten mogelijk query's uitvoeren op de geaggregeerde gegevens.The aggregator might need to take action on event data as it arrives, and external clients may need to query the aggregated data.

Aggregatie diagram

Het lastiger zijn om dit patroon te implementeren met normale, stateless functies is dat gelijktijdigheids beheer een enorme uitdaging wordt.The tricky thing about trying to implement this pattern with normal, stateless functions is that concurrency control becomes a huge challenge. U hoeft zich geen zorgen te maken over meerdere threads die tegelijkertijd dezelfde gegevens wijzigen. u moet er ook voor zorgen dat de aggregator alleen op één virtuele machine tegelijk wordt uitgevoerd.Not only do you need to worry about multiple threads modifying the same data at the same time, you also need to worry about ensuring that the aggregator only runs on a single VM at a time.

Met behulp van een duurzame entiteits functiekan dit patroon eenvoudig als één functie worden geïmplementeerd.Using a Durable Entity function, one can implement this pattern easily as a single function.

[FunctionName("Counter")]
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
{
    int currentValue = ctx.GetState<int>();

    switch (ctx.OperationName.ToLowerInvariant())
    {
        case "add":
            int amount = ctx.GetInput<int>();
            currentValue += amount;
            break;
        case "reset":
            currentValue = 0;
            break;
        case "get":
            ctx.Return(currentValue);
            break;
    }

    ctx.SetState(currentValue);
}

Duurzame entiteiten kunnen ook worden gemodelleerd als .NET-klassen.Durable Entities can also be modeled as .NET classes. Dit model kan nuttig zijn als de lijst met bewerkingen is opgelost en groot wordt.This model can be useful if the list of operations is fixed and becomes large. Het volgende voor beeld is een gelijkwaardige implementatie Counter van de entiteit met behulp van .net-klassen en-methoden.The following example is an equivalent implementation of the Counter entity using .NET classes and methods.

public class Counter
{
    [JsonProperty("value")]
    public int CurrentValue { get; set; }

    public void Add(int amount) => this.CurrentValue += amount;

    public void Reset() => this.CurrentValue = 0;

    public int Get() => this.CurrentValue;

    [FunctionName(nameof(Counter))]
    public static Task Run([EntityTrigger] IDurableEntityContext ctx)
        => ctx.DispatchAsync<Counter>();
}

Clients kunnen bewerkingen in de wachtrij plaatsen voor (ook wel ' Signa lering ' genoemd) een entiteits functie met de client bindingvan de entiteit.Clients can enqueue operations for (also known as "signaling") an entity function using the entity client binding.

[FunctionName("EventHubTriggerCSharp")]
public static async Task Run(
    [EventHubTrigger("device-sensor-events")] EventData eventData,
    [OrchestrationClient] IDurableOrchestrationClient entityClient)
{
    var metricType = (string)eventData.Properties["metric"];
    var delta = BitConverter.ToInt32(eventData.Body, eventData.Body.Offset);

    // The "Counter/{metricType}" entity is created on-demand.
    var entityId = new EntityId("Counter", metricType);
    await entityClient.SignalEntityAsync(entityId, "add", delta);
}

Dynamische gegenereerde proxy's zijn ook beschikbaar voor het verzenden van een signaal entiteit op een type veilige manier.Dynamically generated proxies are also available for signaling entities in a type-safe way. Naast Signa lering kunnen clients ook een query uitvoeren op de status van een entiteit functie met behulp van type veilige methoden op de Orchestration-client binding.And in addition to signaling, clients can also query for the state of an entity function using type-safe methods on the orchestration client binding.

Notitie

Entiteits functies zijn momenteel alleen beschikbaar in .NET als onderdeel van de Durable Functions 2,0 Preview.Entity functions are currently only available in .NET as part of the Durable Functions 2.0 preview.

De technologieThe technology

Achter de schermen is de uitbrei ding van de Durable Functions gebaseerd op het duurzame taak raamwerk, een open-source bibliotheek op github die wordt gebruikt voor het bouwen van werk stromen in code.Behind the scenes, the Durable Functions extension is built on top of the Durable Task Framework, an open-source library on GitHub that's used to build workflows in code. Net als Azure Functions is de serverloze evolutie van Azure WebJobs, Durable Functions de serverloze evolutie van het duurzame taak raamwerk.Like Azure Functions is the serverless evolution of Azure WebJobs, Durable Functions is the serverless evolution of the Durable Task Framework. Micro soft en andere organisaties gebruiken het duurzame taak raamwerk uitgebreid om essentiële processen te automatiseren.Microsoft and other organizations use the Durable Task Framework extensively to automate mission-critical processes. Het is natuurlijk geschikt voor de serverloze Azure Functions omgeving.It's a natural fit for the serverless Azure Functions environment.

Code beperkingenCode constraints

Orchestrator-functies hebben een set coderings regels die moeten worden gevolgd om betrouw bare en langdurige uitvoerings garanties te bieden.In order to provide reliable and long-running execution guarantees, orchestrator functions have a set of coding rules that must be followed. Zie het artikel Orchestrator functie code constraints voor meer informatie.For more information, see the Orchestrator function code constraints article.

BillingBilling

Durable Functions worden op dezelfde manier in rekening gebracht als Azure Functions.Durable Functions are billed the same as Azure Functions. Zie voor meer informatie, prijzen van Azure Functions.For more information, see Azure Functions pricing. Bij het uitvoeren van Orchestrator-functies in het Azure Functions verbruiks abonnement, zijn er enkele facturerings gedrag van belang.When executing orchestrator functions in the Azure Functions Consumption plan, there are some billing behaviors to be aware of. Zie het artikel over Durable functions facturering voor meer informatie over deze problemen.For more information on these behaviors, see the Durable Functions billing article.

Duik er meteen inJump right in

U kunt in minder dan 10 minuten aan de slag gaan met Durable Functions door een van deze taalspecifieke quickstart-zelfstudies te volgen:You can get started with Durable Functions in under 10 minutes by completing one of these language-specific quickstart tutorials:

In beide quickstarts maakt en test u een lokale ‘hallo wereld’-duurzame functie.In both quickstarts, you locally create and test a "hello world" durable function. Vervolgens publiceert u de functiecode op Azure.You then publish the function code to Azure. De functie die u maakt, organiseert en koppelt aanroepen naar andere functies.The function you create orchestrates and chains together calls to other functions.

Meer informatieLearn more

De volgende video laat de voordelen van Durable Functions zien:The following video highlights the benefits of Durable Functions:

Voor een uitgebreidere bespreking van Durable Functions en de onderliggende technologie raadpleegt u de volgende video (deze is gericht op .NET, maar de concepten zijn ook van toepassing op andere ondersteunde talen):For a more in-depth discussion of Durable Functions and the underlying technology, see the following video (it's focused on .NET, but the concepts also apply to other supported languages):

Omdat Durable Functions een geavanceerde extensie voor Azure Functions is, is het niet geschikt voor alle toepassingen.Because Durable Functions is an advanced extension for Azure Functions, it isn't appropriate for all applications. Zie voor een vergelijking met andere Azure-technologieën Compare Azure Functions and Azure Logic Apps.For a comparison with other Azure orchestration technologies, see Compare Azure Functions and Azure Logic Apps.

Volgende stappenNext steps