نمط تسلسل الدوال

تسلسل الدوال هو نمط تقوم فيه بتشغيل تسلسل من الدوال بالترتيب. من الشائع تمرير مخرج دالة إلى مدخل دالة أخرى. تصف هذه المقالة تسلسل التسلسل الذي تبنيه عند إكمال Durable Functions البدء السريع (C#‎, JavaScript, TypeScript, Python, PowerShell، أو Java). تعرف على المزيد في نظرة عامة Durable Functions.

المتطلبات المسبقه

تسلسل الدوال هو نمط تقوم فيه بتشغيل تسلسل من الأنشطة بالترتيب. من الشائع تمرير مخرج نشاط إلى مدخل النشاط التالي. تصف هذه المقالة تسلسل التسلسل لمجموعات تطوير المهام المتطورة لأنظمة .NET وJavaScript وPython وJava.

الدوال في عينة التسلسل

تصف هذه المقالة هذه الوظائف في التطبيق النموذجي:

  • E1_HelloSequence: وظيفة أوركستراتور تستدعي E1_SayHello عدة مرات بالتتابع. يخزن كل مخرج ويسجل النتائج.
  • E1_SayHello: دالة نشاط تضيف "مرحبا" إلى بداية السلسلة.
  • HttpStart: دالة عميل دائمة تعمل بتقنية HTTP وتبدأ نسخة من المنسق.

تصف هذه المقالة هذه المكونات في التطبيق النموذجي:

  • GreetingOrchestration, greetingOrchestrator, function_chaining_orchestrator, أو: ActivityChainingمنسق موسيقي يستدعي عدة أنشطة بالتتابع. يخزن كل مخرج ويسجل النتائج.
  • وظائف النشاط: أنشطة تعالج المدخلات وترجع النتائج. كل نشاط يقوم بتحويل بسيط على المدخل.
  • العميل: تطبيق عميل يبدأ نسخة من المنظم وينتظر النتيجة.

كود وظيفة المنسق

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

يجب أن تحتوي جميع دوال التنسيق على C# على معلمة من النوع DurableOrchestrationContext، والتي توجد في تجميع Microsoft.Azure.WebJobs.Extensions.DurableTask. يتيح لك هذا السياق استدعاء وظائف نشاط أخرى وتمرير معلمات الإدخال باستخدام CallActivityAsync أسلوبها.

استدعاء التعليمات البرمجية E1_SayHello ثلاث مرات في تسلسل مع قيم معلمة مختلفة. تتم إضافة قيمة الإرجاع لكل استدعاء إلى outputs القائمة التي يتم إرجاعها في نهاية الدالة.

يظهر هذا الكود منسقا يقوم باستدعاء ثلاث أنشطة متتالية ويمرر كل مخرج إلى النشاط التالي:

using System.Threading.Tasks;
using Microsoft.DurableTask;

[DurableTask]
public class GreetingOrchestration : TaskOrchestrator<string, string>
{
    public override async Task<string> RunAsync(TaskOrchestrationContext context, string name)
    {
        // Step 1: Say hello to the person
        string greeting = await context.CallActivityAsync<string>(nameof(SayHelloActivity), name);

        // Step 2: Process the greeting
        string processedGreeting = await context.CallActivityAsync<string>(nameof(ProcessGreetingActivity), greeting);

        // Step 3: Finalize the response
        string finalResponse = await context.CallActivityAsync<string>(nameof(FinalizeResponseActivity), processedGreeting);

        return finalResponse;
    }
}

جميع .NET الموزعين ورثوا من TaskOrchestrator<TInput, TOutput>. TaskOrchestrationContext تتيح لك استدعاء الأنشطة باستخدام CallActivityAsync. يستدعي الكود ثلاث أنشطة متتالية، حيث يستقبل كل نشاط مخرجات النشاط السابق.

رمز دالة النشاط

[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
    string name = context.GetInput<string>();
    return $"Hello {name}!";
}

تستخدم الأنشطة ActivityTrigger السمة. استخدامه IDurableActivityContext لإجراءات النشاط، مثل قراءة المدخلات باستخدام GetInput<T>.

E1_SayHello يشكل سلسلة تحية.

بدلا من الربط ب IDurableActivityContext، اربط مباشرة بالنوع الذي يمرر إلى دالة النشاط. على سبيل المثال:

[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

الأنشطة في مجموعة تطوير المهام الدائمة ترث من TaskActivity<TInput, TOutput>:

using System.Threading.Tasks;
using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;

[DurableTask]
public class SayHelloActivity : TaskActivity<string, string>
{
    private readonly ILogger<SayHelloActivity> _logger;

    public SayHelloActivity(ILogger<SayHelloActivity> logger)
    {
        _logger = logger;
    }

    public override Task<string> RunAsync(TaskActivityContext context, string name)
    {
        _logger.LogInformation("Activity SayHello called with name: {Name}", name);
        return Task.FromResult($"Hello {name}!");
    }
}

[DurableTask]
public class ProcessGreetingActivity : TaskActivity<string, string>
{
    public override Task<string> RunAsync(TaskActivityContext context, string greeting)
    {
        return Task.FromResult($"{greeting} How are you today?");
    }
}

[DurableTask]
public class FinalizeResponseActivity : TaskActivity<string, string>
{
    public override Task<string> RunAsync(TaskActivityContext context, string response)
    {
        return Task.FromResult($"{response} I hope you're doing well!");
    }
}

استخدم حقن الاعتماد للحصول على خدمات مثل ILogger. أضف السمة [DurableTask] لتسجيل النشاط مع العامل.

كود العميل لبدء التوزيع الموسيقي

ابدأ نسخة دالة منسق من دالة عميل. استخدم الدالة HttpStart التي تعمل ب HTTP لبدء مثيلات .E1_HelloSequence

public static class HttpStart
{
    [FunctionName("HttpStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
        [DurableClient] IDurableClient starter,
        string functionName,
        ILogger log)
    {
        // Function input comes from the request content.
        object eventData = await req.Content.ReadAsAsync<object>();
        string instanceId = await starter.StartNewAsync(functionName, eventData);

        log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}

للتفاعل مع الموزعين، أضف DurableClient ربط إدخال. استخدم العميل لبدء التنسيق وإرجاع استجابة HTTP تتضمن عناوين URL للتحقق من حالة التوزيع الجديد.

ابدأ التنسيق من تطبيق عميل. العميل يحدد جدولة التوزيع ويمكنه الانتظار حتى الانتهاء.

using System;
using Microsoft.DurableTask.Client;

// Create the client
var client = DurableTaskClientBuilder.UseDurableTaskScheduler(connectionString).Build();

// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
    nameof(GreetingOrchestration),
    input: "World");

Console.WriteLine($"Started orchestration with ID: {instanceId}");

// Wait for the orchestration to complete
OrchestrationMetadata result = await client.WaitForInstanceCompletionAsync(
    instanceId,
    getInputsAndOutputs: true);

Console.WriteLine($"Orchestration completed with result: {result.ReadOutputAs<string>()}");

أنشئ DurableTaskClient باستخدام connection string إلى جدولة المهام الدائمة. استخدمها ScheduleNewOrchestrationInstanceAsync لبدء توزيع موسيقي وانتظار WaitForInstanceCompletionAsync الانتهاء.

شغل عينة تسلسل الدوال

لتشغيل التنسيق E1_HelloSequence ، أرسل طلب HTTP POST هذا إلى الدالة HttpStart .

POST http://{host}/orchestrators/E1_HelloSequence

ملحوظة

يفترض مقتطف HTTP السابق أن ملف host.json الخاص بالعينة يزيل البادئة الافتراضية api/ من جميع عناوين دوال المشغلات الخاصة ب HTTP. ابحث عن هذا التكوين في ملف host.json العينة.

على سبيل المثال، إذا كنت تشغل العينة في تطبيق دالة يسمى myfunctionapp، استبدل {host} ب myfunctionapp.azurewebsites.net.

يعيد الطلب HTTP 202 (تم تقليمه للاختصار):

HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

(...trimmed...)

يبدأ التوزيع الموسيقي في الانتظار ويبدأ العمل فورا. استخدم رابط العنوان في الرأس Location للتحقق من حالة التنفيذ.

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

يظهر الرد حالة التوزيع الأوركسترالي. وبما أنه ينتهي بسرعة، غالبا ما يكون المثيل في حالة الاكتمال ويعيد ردا مثل هذا (تم تقليصه للاختصار):

HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8

{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}

النسخة runtimeStatusمكتملة، وتحتوي output على النتيجة المتسلسلة JSON لتنفيذ وظيفة المنسق.

ملحوظة

تنفيذ منطق بداية مشابه لأنواع الزناد الأخرى، مثل queueTrigger، eventHubTrigger، أو timerTrigger.

راجع سجلات تنفيذ الوظائف. تبدأ الدالة E1_HelloSequence وتكتمل عدة مرات بسبب سلوك إعادة التشغيل الموصوف في موثوقية التوزيع الأوركسترالي. لكنها E1_SayHello تعمل فقط ثلاث مرات لأن تنفيذ وظائف النشاط لا يعاد تشغيله.

لتشغيل العينة، تحتاج:

  1. تشغيل محاكي جدولة المهام الدائم (للتطوير المحلي):

    docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latest
    
  2. ابدأ العامل بتسجيل المنظم والأنشطة.

  3. شغل العميل لجدولة توزيع موسيقي وانتظر النتيجة.

يظهر مخرجات العميل نتيجة التوزيع المتسلسل:

Started orchestration with ID: abc123
Orchestration completed with result: "Hello World! How are you today? I hope you're doing well!"

تظهر سجلات العامل تشغيل كل نشاط بالتسلسل ويمرر مخرجاته إلى النشاط التالي.

الخطوات التالية

توضح هذه العينة توزيع توزيع بسيط لسلسلة الدوال. بعد ذلك، نفذ نمط المروحة/المروحة الداخلية.

توضح هذه العينة توزيع توزيع بسيط لسلسلة الدوال. بعد ذلك، استكشف المزيد من الأنماط.

للحصول على أمثلة كاملة لمجموعات تطوير جافا سكريبت (JavaScript SDK)، راجع عينات SDK لجافا سكريبت للمهام المتينة.