Mi a Durable Functions?What are Durable Functions?

A Durable Functions Azure functions , amely lehetővé teszi állapot-nyilvántartó függvények írását kiszolgáló nélküli számítási környezetben.Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless compute environment. A bővítmény lehetővé teszi az állapot-nyilvántartó munkafolyamatok definiálását a Orchestrator függvények és az állapot-nyilvántartó entitások írásával az Azure functions programozási modellel az Entity functions használatával.The extension lets you define stateful workflows by writing orchestrator functions and stateful entities by writing entity functions using the Azure Functions programming model. A háttérben a bővítmény kezeli az állapotot, az ellenőrzőpontokat és az újraindításokat, így Ön az üzleti logikára koncentrálhat.Behind the scenes, the extension manages state, checkpoints, and restarts for you, allowing you to focus on your business logic.

Támogatott nyelvekSupported languages

A Durable Functions jelenleg a következő nyelveket támogatja:Durable Functions currently supports the following languages:

  • C# : mindkét előre lefordított osztály kódtára és C# parancsfájl.C#: both precompiled class libraries and C# script.
  • F# : előre lefordított osztály kódtárak és F# szkriptek.F#: precompiled class libraries and F# script. F#a parancsfájl csak az Azure Functions futtatókörnyezet 1. x verziója esetén támogatott.F# script is only supported for version 1.x of the Azure Functions runtime.
  • JavaScript: csak az Azure functions futtatókörnyezet 2. x verziójára támogatott.JavaScript: supported only for version 2.x of the Azure Functions runtime. A Durable Functions-bővítmény vagy újabb verzió 1.7.0 szükséges.Requires version 1.7.0 of the Durable Functions extension, or a later version.

Durable Functions célja az összes Azure functions nyelvtámogatása.Durable Functions has a goal of supporting all Azure Functions languages. További nyelvek támogatásához tekintse meg a Durable functions problémák listáját a legújabb munkaállapotról.See the Durable Functions issues list for the latest status of work to support additional languages.

A Azure Functionshoz hasonlóan a Visual studio 2019, a Visual Studio Codeés a Azure Portalhasználatával is készíthet durable Functionseket.Like Azure Functions, there are templates to help you develop Durable Functions using Visual Studio 2019, Visual Studio Code, and the Azure portal.

AlkalmazásmintákApplication patterns

Durable Functions elsődleges használati esete az összetett, állapot-nyilvántartó koordinációs követelmények leegyszerűsítése a kiszolgáló nélküli alkalmazásokban.The primary use case for Durable Functions is simplifying complex, stateful coordination requirements in serverless applications. A következő szakaszok ismertetik azokat a tipikus alkalmazási mintákat, amelyek a Durable Functions számára hasznosak lehetnek:The following sections describe typical application patterns that can benefit from Durable Functions:

Minta #1: FüggvényláncolásPattern #1: Function chaining

A függvény láncolása mintában a függvények sorrendje egy adott sorrendben fut le.In the function chaining pattern, a sequence of functions executes in a specific order. Ebben a mintában egy függvény kimenetét egy másik függvény bemenetére alkalmazza a rendszer.In this pattern, the output of one function is applied to the input of another function.

A függvény láncolási mintájának ábrája

Az Durable Functions használatával a függvény láncolása minta tömören valósítható meg, ahogy az alábbi példában is látható: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", null);
        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.
    }
}

JavaScript (csak 2. x függvény)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);
});

Ebben a példában a függvény alkalmazásban F2az F3értékek F1, F4 a, és a más függvények nevei szerepelnek.In this example, the values F1, F2, F3, and F4 are the names of other functions in the function app. A vezérlési folyamat normál, kötelező kódolási szerkezetek használatával valósítható meg.You can implement control flow by using normal imperative coding constructs. A kód felülről lefelé fut.Code executes from the top down. A kód a meglévő nyelvi vezérlési folyamatokat, például a feltételes és a hurkokat is magában foglalja.The code can involve existing language control flow semantics, like conditionals and loops. A try blokkokban a catch /hibákkezeléséreszolgáló logikaisfelvehető/. finallyYou can include error handling logic in try/catch/finally blocks.

A context (z) [DurableOrchestrationContext] (.net) és az context.df Object (JavaScript) paraméterrel más függvényeket hívhat meg név, pass paraméterek és Return Function kimenet használatával.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. Minden alkalommal, amikor a await kódC#meghívja yield () vagy (JavaScript), a Durable functions Framework ellenőrzőpontja az aktuális függvény példányának előrehaladását.Each time the code calls await (C#) or yield (JavaScript), the Durable Functions framework checkpoints the progress of the current function instance. Ha a folyamat vagy a virtuális gép a végrehajtás során újra újraindul, a függvény példánya az előző await vagy yield a hívásból folytatódik.If the process or VM recycles midway through the execution, the function instance resumes from the preceding await or yield call. További információkért lásd a következő, minta #2: Ventilátor ki-és bevezetését.For more information, see the next section, Pattern #2: Fan out/fan in.

Megjegyzés

A context JavaScriptben lévő objektum a teljes függvény környezetétjelenti, nem csak a [DurableOrchestrationContext] paramétert.The context object in JavaScript represents the entire function context, not only the [DurableOrchestrationContext] parameter.

Minta #2: VentilátorPattern #2: Fan out/fan in

A fan out/Fan in mintában több függvényt hajt végre párhuzamosan, majd várjon, amíg az összes függvény befejeződik.In the fan out/fan in pattern, you execute multiple functions in parallel and then wait for all functions to finish. Gyakran előfordul, hogy egyes összesítési műveletek a függvények által visszaadott eredményeken is megtörténik.Often, some aggregation work is done on the results that are returned from the functions.

A ventilátor kikapcsolási/ventilátor mintázatának ábrája

A normál függvények segítségével kipróbálhatja, hogy a függvény több üzenetet küld egy várólistára.With normal functions, you can fan out by having the function send multiple messages to a queue. A Fanning sokkal nagyobb kihívást jelent.Fanning back in is much more challenging. Ahhoz, hogy egy normál függvényben bekapcsolja a ventilátort, kódot írhat, amely nyomon követheti a várólista által aktivált függvények befejezését, majd tárolhatja a függvény kimeneteit.To fan in, in a normal function, you write code to track when the queue-triggered functions end, and then store function outputs.

A Durable Functions bővítmény ezt a mintát viszonylag egyszerű kóddal kezeli: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", null);
    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);
}

JavaScript (csak 2. x függvény)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);
});

A rendszer a F2 függvény több példányára terjeszti a kivezetési munkát.The fan-out work is distributed to multiple instances of the F2 function. A rendszer a feladatok dinamikus listájának használatával követi nyomon a munkát.The work is tracked by using a dynamic list of tasks. A rendszer Task.WhenAll meghívja a context.df.Task.all .NET API-t vagy a JavaScript API-t, hogy megvárja az összes meghívott függvény befejeződését.The .NET Task.WhenAll API or JavaScript context.df.Task.all API is called, to wait for all the called functions to finish. Ezután a rendszer F2 összesíti a függvény kimeneteit a dinamikus feladatlistából, és átadja a F3 függvénynek.Then, the F2 function outputs are aggregated from the dynamic task list and passed to the F3 function.

Az automatikus await ellenőrzőpontok, amelyek a vagy yield a hívásakor Task.WhenAll történnek, vagy context.df.Task.all biztosítják, hogy egy lehetséges Midway-összeomlás vagy-újraindítás nem igényli a már befejezett feladatok újraindítását.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.

Megjegyzés

Ritka körülmények között előfordulhat, hogy az ablak összeomlása egy tevékenységi függvény befejeződése után következik be, de a befejezését a rendszer a előkészítési előzményekbe menti.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. Ha ez történik, a tevékenység függvény a folyamat helyreállítása után újraindul.If this happens, the activity function would re-run from the beginning after the process recovers.

Minta #3: Aszinkron HTTP API-kPattern #3: Async HTTP APIs

Az aszinkron HTTP API-minta a hosszan futó műveletek állapotának a külső ügyfelekkel való koordinálásával kapcsolatos problémát orvosolja.The async HTTP API pattern addresses the problem of coordinating the state of long-running operations with external clients. Ennek a mintának a megvalósításának általános módja, ha egy HTTP-végpont aktiválja a hosszan futó műveletet.A common way to implement this pattern is by having an HTTP endpoint trigger the long-running action. Ezt követően irányítsa át az ügyfelet egy olyan állapot-végpontra, amelyet az ügyfél lekérdez, hogy megtudja, mikor fejeződött be a művelet.Then, redirect the client to a status endpoint that the client polls to learn when the operation is finished.

A HTTP API mintájának ábrája

A Durable Functions beépített támogatást nyújt ehhez a mintához, egyszerűsítve vagy akár el is távolítja a kódot, amelyet a hosszú ideig futó függvények végrehajtásához kell írnia.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. Például a Durable Functions gyors üzembe helyezési mintákC# (és a JavaScript) egy egyszerű Rest-parancsot mutatnak be, amelyet az új Orchestrator-függvények indításához használhat.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. Egy példány elindítása után a bővítmény elérhetővé teszi a Orchestrator függvény állapotát lekérdező webhook HTTP API-kat.After an instance starts, the extension exposes webhook HTTP APIs that query the orchestrator function status.

Az alábbi példa olyan REST-parancsokat mutat be, amelyek elindítják a Orchestrator, és lekérdezik az állapotát.The following example shows REST commands that start an orchestrator and query its status. Az érthetőség kedvéért a protokollok egyes részletei kimaradnak a példából.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", ...}

Mivel a Durable Functions futtatókörnyezet kezeli az állapotot, nincs szükség saját állapot-követési mechanizmus megvalósítására.Because the Durable Functions runtime manages state for you, you don't need to implement your own status-tracking mechanism.

A Durable Functions bővítmény elérhetővé teszi a hosszú ideig futó munkafolyamatokat kezelő beépített HTTP API-kat.The Durable Functions extension exposes built-in HTTP APIs that manage long-running orchestrations. Azt is megteheti, hogy saját függvény-eseményindítókat (például HTTP, üzenetsor vagy Azure Event Hubs) és a koordináló ügyfél- kötésthasználva saját maga is megvalósíthatja ezt a mintát.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. Előfordulhat például, hogy üzenetsor-üzenetet használ a megszakítás elindításához.For example, you might use a queue message to trigger termination. Vagy használhat olyan HTTP-triggert, amelyet egy Azure Active Directory hitelesítési házirend véd, és nem a beépített HTTP API-kat, amelyek a hitelesítéshez generált kulcsot használnak.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.

További információkért lásd a http- szolgáltatások című cikket, amely ismerteti, hogyan teheti elérhetővé az aszinkron, hosszan futó FOLYAMATokat http-n keresztül a Durable functions bővítménnyel.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.

Minta #4: FigyelésPattern #4: Monitor

A figyelő minta egy rugalmas, ismétlődő folyamatra hivatkozik egy munkafolyamatban.The monitor pattern refers to a flexible, recurring process in a workflow. Egy példa egy lekérdezésre, amíg az adott feltételek teljesülnek.An example is polling until specific conditions are met. Egy alapszintű forgatókönyv , például egy rendszeres karbantartási feladat, az intervallum statikus, a példányok élettartamának kezelése pedig összetett lesz.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. A Durable Functions használatával rugalmas ismétlődési időközöket hozhat létre, kezelheti a feladatok élettartamát, és több figyelő folyamat is létrehozható egyetlen előkészítéssel.You can use Durable Functions to create flexible recurrence intervals, manage task lifetimes, and create multiple monitor processes from a single orchestration.

A figyelő minta példája a korábbi aszinkron HTTP API-forgatókönyv fordítottja.An example of the monitor pattern is to reverse the earlier async HTTP API scenario. Ahelyett, hogy egy külső ügyfél végpontját kitéve egy hosszan futó művelet figyelésére, a hosszan futó figyelő külső végpontot használ, majd megvárja az állapot változását.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.

A figyelő mintájának ábrája

Néhány sornyi kódban a Durable Functions használatával több, tetszőleges végpontokat figyelő figyelőt hozhat létre.In a few lines of code, you can use Durable Functions to create multiple monitors that observe arbitrary endpoints. A figyelők a feltételek teljesülése esetén a végrehajtás végén, vagy a DurableOrchestrationClient megszakítják a figyelőket.The monitors can end execution when a condition is met, or the DurableOrchestrationClient can terminate the monitors. Egy adott feltétel alapján módosíthatja a wait figyelő intervallumát (például exponenciális leállítási.)You can change a monitor's wait interval based on a specific condition (for example, exponential backoff.)

A következő kód egy alapszintű figyelőt valósít meg: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.
}

JavaScript (csak 2. x függvény)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.
});

A kérés fogadásakor a rendszer létrehoz egy új előkészítési példányt az adott AZONOSÍTÓJÚ feladatokhoz.When a request is received, a new orchestration instance is created for that job ID. A példány lekérdezi az állapotot, amíg a feltétel teljesül, és a hurok ki van zárva.The instance polls a status until a condition is met and the loop is exited. A tartós időzítő vezérli a lekérdezési időközt.A durable timer controls the polling interval. Ezt követően több munka is elvégezhető, vagy az előkészítés véget ért.Then, more work can be performed, or the orchestration can end. Ha a context.CurrentUtcDateTime (.net) vagy context.df.currentUtcDateTime (JavaScript) érték meghaladja expiryTime a értéket, a figyelő véget ér.When the context.CurrentUtcDateTime (.NET) or context.df.currentUtcDateTime (JavaScript) exceeds the expiryTime value, the monitor ends.

Minta #5: Emberi beavatkozásPattern #5: Human interaction

Számos automatizált folyamat tartalmaz valamilyen emberi interakciót.Many automated processes involve some kind of human interaction. Az emberek automatikus folyamatba való bevonása trükkös, mert az emberek nem a lehető legszélesebb körben elérhetők és a Cloud Services-ként reagálnakInvolving humans in an automated process is tricky because people aren't as highly available and as responsive as cloud services. Az automatikus folyamat az időtúllépések és a kompenzációs logika használatával lehetővé teheti az ilyen interakciókat.An automated process might allow for this interaction by using timeouts and compensation logic.

A jóváhagyási folyamat olyan üzleti folyamatra mutat példát, amely emberi interakciót is magában foglal.An approval process is an example of a business process that involves human interaction. Előfordulhat, hogy a felettes jóváhagyása egy olyan Költségjelentés esetében szükséges, amely meghaladja az adott dollár mennyiségét.Approval from a manager might be required for an expense report that exceeds a certain dollar amount. Ha a kezelő nem hagyja jóvá a költségjelentés 72 órán belül történő jóváhagyását (lehet, hogy a felettes a vakáción ment), a eszkalációs folyamat beolvassa a-t, hogy valaki más (például a felettes felettese) jóváhagyást kapjon.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).

Az emberi interakció mintájának ábrája

Ebben a példában egy Orchestrator függvény használatával valósítható meg a minta.You can implement the pattern in this example by using an orchestrator function. A Orchestrator tartós időzítőt használ a jóváhagyás kéréséhez.The orchestrator uses a durable timer to request approval. Ha időtúllépés történik, a Orchestrator megnőnek.The orchestrator escalates if timeout occurs. A Orchestrator egy külső eseménytvár, például egy emberi interakció által generált értesítést.The orchestrator waits for an external event, such as a notification that's generated by a human interaction.

Ezek a példák jóváhagyási folyamatot hoznak létre az emberi interakciós minta bemutatásához: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", null);
    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", null);
        }
    }
}

JavaScript (csak 2. x függvény)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");
    }
});

Tartós időzítő, hívás context.CreateTimer (.net) vagy context.df.createTimer (JavaScript) létrehozásához.To create the durable timer, call context.CreateTimer (.NET) or context.df.createTimer (JavaScript). Az értesítést a context.WaitForExternalEvent (.net) vagy context.df.waitForExternalEvent a (JavaScript) fogadja.The notification is received by context.WaitForExternalEvent (.NET) or context.df.waitForExternalEvent (JavaScript). Ezt követően a context.df.Task.any Task.WhenAny (.net) vagy (JavaScript) metódust kell eldöntenie, hogy megtörténjen-e a kiterjesztés (időtúllépés történik), vagy dolgozza fel a jóváhagyást (a jóváhagyás az időkorlát előtt érkezik).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).

Egy külső ügyfél a beépített http API -kkal vagy a DurableOrchestrationClient. RaiseEventAsync API-val egy másik függvény használatával kézbesítheti az esemény-értesítést a várakozó Orchestrator függvénynek: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"

Minta #6: Összesítő (előzetes verzió)Pattern #6: Aggregator (preview)

A hatodik minta az események adatainak egy adott, címezhető entitásbavaló összesítésére szolgál.The sixth pattern is about aggregating event data over a period of time into a single, addressable entity. Ebben a mintában az összesíteni kívánt adatok több forrásból származhatnak, a kötegekben is elhelyezhetők, vagy hosszú időn keresztül elszórtan lehetnek.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. Előfordulhat, hogy a gyűjtőnek műveleteket kell végeznie az események érkezésekor, és előfordulhat, hogy a külső ügyfeleknek le kell kérdezni az összesített adatokat.The aggregator might need to take action on event data as it arrives, and external clients may need to query the aggregated data.

Összesítő diagram

A minta a normál, állapot nélküli függvények használatával történő megvalósítására tett kísérlet során az, hogy a Egyidejűség-vezérlés óriási kihívás lesz.The tricky thing about trying to implement this pattern with normal, stateless functions is that concurrency control becomes a huge challenge. Nem csupán annyit kell aggódnia, hogy ugyanazokat az információkat egyszerre több szálra módosítja, azonban azt is meg kell aggódnia, hogy a gyűjtő egyszerre csak egyetlen virtuális gépen fut.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.

Egy tartós entitás függvényhasználatával egyetlen függvényként egyszerűen megvalósíthatja ezt a mintát.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);
}

A tartós entitások .NET-osztályként is modellezésre használhatók.Durable Entities can also be modeled as .NET classes. Ez a modell akkor lehet hasznos, ha a műveletek listája rögzített, és nagy lesz.This model can be useful if the list of operations is fixed and becomes large. A következő példa az Counter entitás egyenértékű implementációját használja .net-osztályok és-metódusok használatával.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>();
}

Az ügyfelek az entitás- ügyfél kötésénekhasználatával sorba helyezni műveleteket (más néven "jelzés").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);
}

A dinamikusan generált proxyk is elérhetők az entitások típus-biztonságos módon történő jelzéséhez.Dynamically generated proxies are also available for signaling entities in a type-safe way. Továbbá a jelzésen felül az ügyfelek az entitások függvényének állapotáról is lekérhetik a típus-biztonságos metódusok használatával.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.

Megjegyzés

Az Entity functions jelenleg csak a .NET-ben érhető el a Durable Functions 2,0 előzetesverziójának részeként.Entity functions are currently only available in .NET as part of the Durable Functions 2.0 preview.

A technológiaThe technology

A színfalak mögött a Durable Functions-bővítmény a tartós feladatok keretrendszeréreépül, amely egy nyílt forráskódú, a githubon található, a munkafolyamatokat a kódban felépítő könyvtár.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. Például a Azure Functions a Azure WebJobs kiszolgáló nélküli fejlődése, Durable Functions a tartós feladat-keretrendszer kiszolgáló nélküli fejlődése.Like Azure Functions is the serverless evolution of Azure WebJobs, Durable Functions is the serverless evolution of the Durable Task Framework. A Microsoft és más szervezetek széles körben használják a tartós feladatok keretrendszerét a kritikus fontosságú folyamatok automatizálására.Microsoft and other organizations use the Durable Task Framework extensively to automate mission-critical processes. A kiszolgáló nélküli Azure Functions környezet számára természetes módon illeszkedik.It's a natural fit for the serverless Azure Functions environment.

A kód megkötéseiCode constraints

Ahhoz, hogy megbízható és hosszan futó végrehajtási garanciákat lehessen biztosítani, a Orchestrator függvényeknek követniük kell a kódolási szabályok készletét.In order to provide reliable and long-running execution guarantees, orchestrator functions have a set of coding rules that must be followed. További információ: Orchestrator Function Code megkötések cikk.For more information, see the Orchestrator function code constraints article.

SzámlázásBilling

Durable Functions számlázása ugyanaz, mint Azure Functions.Durable Functions are billed the same as Azure Functions. További információkért lásd: Azure Functions árképzése.For more information, see Azure Functions pricing. A Azure Functions használati tervbenszereplő Orchestrator-függvények végrehajtásakor bizonyos számlázási viselkedések ismerete szükséges.When executing orchestrator functions in the Azure Functions Consumption plan, there are some billing behaviors to be aware of. További információ ezekről a viselkedésekről: Durable functions számlázási cikk.For more information on these behaviors, see the Durable Functions billing article.

Ugrás közvetlenül aJump right in

A következő, a nyelvfüggő gyors útmutatók egyikének elvégzésével megkezdheti a Durable Functions használatának megkezdését 10 perc alatt:You can get started with Durable Functions in under 10 minutes by completing one of these language-specific quickstart tutorials:

Mindkét rövid útmutatóban helyileg létrehozhatja és tesztelheti a "Hello World" tartós funkciót.In both quickstarts, you locally create and test a "hello world" durable function. Ezután közzéteheti a függvénykódot az Azure-ban.You then publish the function code to Azure. Az Ön által létrehozott függvény összehangolja és láncokba rendezi a más függvények hívásait.The function you create orchestrates and chains together calls to other functions.

Tudnivalók a modellalapú alkalmazások létrehozásárólLearn more

Az alábbi videó a Durable Functions előnyeit mutatja be:The following video highlights the benefits of Durable Functions:

A Durable Functions és a mögöttes technológia részletes ismertetését lásd az alábbi videóban (ez a .NET-re összpontosít, de a fogalmak más támogatott nyelvekre is érvényesek):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):

Mivel a Durable Functions a Azure functionsspeciális bővítménye, az összes alkalmazás esetében nem megfelelő.Because Durable Functions is an advanced extension for Azure Functions, it isn't appropriate for all applications. Az egyéb Azure-előkészítési technológiákkal való összehasonlításért lásd: Azure functions és Azure Logic apps összehasonlítása.For a comparison with other Azure orchestration technologies, see Compare Azure Functions and Azure Logic Apps.

További lépésekNext steps