مشاركة عبر


إدارة حالات التوزيع الموسيقي

التنسيقات هي سير عمل طويل الأمد بحالة يمكنك تشغيلها، الاستعلام، تعليقها، استئنافها، وإنهاؤها باستخدام واجهات برمجة تطبيقات إدارة مدمجة. في Durable Functions، يكشف ربط عميل orchestration هذه واجهات برمجة التطبيقات. في مجموعات تطوير المهام الدائمة، تتوفر هذه العمليات من خلال الفئة DurableTaskClient . تغطي هذه المقالة جميع عمليات إدارة المثيلات المدعومة لكلا المنصتين.

نصيحة

جدولة المهام المتطورة Azure هي الواجهة الخلفية الموصى بها لكل من Durable Functions وحزمة تطوير المهام الدائمة، وتوفر تجربة مدارة بالكامل بدون خوادم لتشغيل سير العمل المتطور على نطاق واسع.

بدء مثيلات

طريقة start-new (أو schedule-new) على عميل التوزيع تبدأ نسخة تنسيق جديدة. داخليا، تكتب هذه الطريقة رسالة إلى الخلفية المعدة (مثل Durable Task Scheduler أو Azure Storage) ثم تعيد. تقوم هذه الرسالة بتفعيل بدء التوزيع الموسيقي بالاسم المحدد.

إليك المعايير لبدء نسخة جديدة من التوزيع الأوركسترالي:

  • الاسم: اسم دالة المنسق التي يجب جدولتها.
  • الإدخال: أي بيانات JSON قابلة للتسلسل يجب تمريرها كمدخل إلى دالة المنسق.
  • InstanceId: (اختياري) المعرف الفريد للمثيل. إذا لم تحدد هذه المعلمة، فإن الأسلوب يستخدم معرفا عشوائيا.

نصيحة

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

  • الاسم: اسم الفرقة الموسيقية التي يجب جدولتها.
  • الإدخال: أي بيانات قابلة للتسلسل-JSON يجب تمريرها كمدخل إلى التوزيع الموسيقي.
  • InstanceId: (اختياري) المعرف الفريد للمثيل. إذا لم تحدد هذه المعلمة، فإن الأسلوب يستخدم معرفا عشوائيا.

نصيحة

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

تبدأ دالة المثال التالية نسخة توزيع جديدة:

[FunctionName("HelloWorldQueueTrigger")]
public static async Task Run(
    [QueueTrigger("start-queue")] string input,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    string instanceId = await starter.StartNewAsync("HelloWorld", input);
    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

مهم

حاليا، حزمة تطوير المهام الدائمة PowerShell غير متوفرة.

يوضح الكود التالي كيفية بدء نسخة تنسيقية جديدة باستخدام مجموعات SDK للمهام الدائمة:

using Microsoft.DurableTask.Client;

// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("HelloWorld", input);
Console.WriteLine($"Started orchestration with ID = '{instanceId}'.");

// Optionally, wait for the orchestration to start
OrchestrationMetadata metadata = await client.WaitForInstanceStartAsync(instanceId, timeout: TimeSpan.FromSeconds(30));

مثيلات الاستعلام

بعد بدء نسخ تنسيق جديدة، من المرجح أنك بحاجة للاستعلام عن حالة وقت التشغيل الخاصة بها لمعرفة ما إذا كانت تعمل أو مكتملة أو فاشلة.

طريقة الحصول على الحالة على عميل التنسيق تعيد حالة مثيل التنسيق.

يأخذ instanceId (مطلوب) و showHistory (اختياري) showHistoryOutput و(اختياري) و showInput (اختياري) كمعلمات.

  • showHistory: إذا تم تعيينها إلى true، تحتوي الاستجابة على محفوظات التنفيذ.
  • showHistoryOutput: إذا تم تعيينه إلى true، يحتوي سجل التنفيذ على مخرجات النشاط.
  • showInput: إذا تم تعيينه على false، فإن الاستجابة لا تحتوي على مدخل الدالة. القيمة الافتراضية هي true.

يقوم الأسلوب بإرجاع كائن بالخصائص التالية:

  • الاسم: اسم دالة المنسق.
  • InstanceId: معرف المثيل الخاص بالتزامن (يجب أن يكون هو نفس instanceId الإدخال).
  • CreatedTime: الوقت الذي تبدأ فيه وظيفة الموزع في العمل.
  • LastUpdatedTime: الوقت الذي يتوقف فيه التوزيع الأوركسترالي إلى نقاط التفتيش.
  • الإدخال: إدخال الدالة كقيمة JSON. هذا الحقل غير مأهول إذا showInput كان .false
  • CustomStatus: حالة التزامن المخصص بتنسيق JSON.
  • المخرج: مخرج الدالة كقيمة JSON (إذا اكتملت الدالة). إذا فشلت وظيفة المنسق، تشمل هذه الخاصية تفاصيل الفشل. إذا تم تعليق أو إنهاء وظيفة المنسق، فإن هذه الخاصية تشمل سبب التعليق أو الإنهاء (إن وجد).
  • RuntimeStatus: إحدى القيم التالية:
    • قيد الانتظار: تم جدولة النسخة لكنها لم تبدأ بعد في التشغيل.
    • التشغيل: النسخة تعمل.
    • اكتمل: تم الانتهاء من النسخة بشكل طبيعي.
    • تابع كجديد: أعادت النسخة تشغيل نفسها بتاريخ جديد. هذه الحالة هي حالة عابرة.
    • فشل: فشل المثيل مع وجود خطأ.
    • تم إنهاءه: توقفت الحالة فجأة.
    • معلق: يتم تعليق النسخة ويمكن استئنافها في وقت لاحق.
  • المحفوظات: محفوظات تنفيذ التنسيق. يتم ملء هذا الحقل فقط إذا showHistory تم تعيينه إلى true.
  • showHistory: إذا تم تعيينها إلى true، تحتوي الاستجابة على محفوظات التنفيذ.
  • showHistoryOutput: إذا تم تعيينه إلى true، يحتوي سجل التنفيذ على مخرجات النشاط.
  • showInput: إذا تم ضبطه على false، فإن الاستجابة لا تحتوي على مدخلات التوزيع الموسيقي. القيمة الافتراضية هي true.

يقوم الأسلوب بإرجاع كائن بالخصائص التالية:

  • الاسم: اسم الفرقة الموسيقية.
  • InstanceId: معرف المثيل الخاص بالتزامن (يجب أن يكون هو نفس instanceId الإدخال).
  • CreatedTime: الوقت الذي يبدأ فيه التوزيع الأوركسترالي بالتشغيل.
  • LastUpdatedTime: الوقت الذي يتوقف فيه التوزيع الأوركسترالي إلى نقاط التفتيش.
  • الإدخال: إدخال التوزيع كقيمة JSON. هذا الحقل غير مأهول إذا showInput كان .false
  • CustomStatus: حالة التزامن المخصص بتنسيق JSON.
  • المخرج: مخرج التوزيع كقيمة JSON (إذا اكتمل التوزيع الموسيقي). إذا فشل التنسيق، تشمل هذه الخاصية تفاصيل الفشل. إذا تم تعليق أو إنهاء التنظيم، فإن هذه الخاصية تشمل سبب الإيقاف أو الإنهاء (إن وجد).
  • RuntimeStatus: إحدى القيم التالية:
    • قيد الانتظار: تم جدولة النسخة لكنها لم تبدأ بعد في التشغيل.
    • التشغيل: النسخة تعمل.
    • اكتمل: تم الانتهاء من النسخة بشكل طبيعي.
    • تابع كجديد: أعادت النسخة تشغيل نفسها بتاريخ جديد. هذه الحالة هي حالة عابرة.
    • فشل: فشل المثيل مع وجود خطأ.
    • تم إنهاءه: توقفت الحالة فجأة.
    • معلق: يتم تعليق النسخة ويمكن استئنافها في وقت لاحق.
  • المحفوظات: محفوظات تنفيذ التنسيق. يتم ملء هذا الحقل فقط إذا showHistory تم تعيينه إلى true.

ملحوظة

لا يتم وضع علامة على الموزع حتى Completed تنتهي جميع مهامه المجدولة ويعود الموزع. بعبارة أخرى، ليس كافيا أن يصل الموزع إلى بيانه return ليتم تمييزه ك Completed. وهذا مهم بشكل خاص في الحالات التي WhenAny يستخدم؛ غالبا return ما يكون هؤلاء المنظمون قبل تنفيذ جميع المهام المجدولة.

تعود هذه الطريقة ب null (.NET و Java)، undefined (جافا سكريبت)، أو None (Python) إذا لم يكن المثيل موجودا.

[FunctionName("GetStatus")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("check-status-queue")] string instanceId)
{
    DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);
    // do something based on the current status.
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

// Get the status of an orchestration instance
OrchestrationMetadata? metadata = await client.GetInstanceAsync(instanceId, getInputsAndOutputs: true);
if (metadata != null)
{
    OrchestrationRuntimeStatus status = metadata.RuntimeStatus;
    // do something based on the current status
}

الاستعلام عن جميع المثيلات

يمكنك استخدام واجهات برمجة التطبيقات بلغتك SDK للاستعلام عن حالات جميع مثيلات التنسيق في مركز المهام. تقوم واجهة برمجة التطبيقات هذه "list-instances" أو "get-status" بإرجاع قائمة الكائنات التي تمثل مثيلات التنسيق المطابقة لمعلمات الاستعلام.

[FunctionName("GetAllStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var noFilter = new OrchestrationStatusQueryCondition();
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        noFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }

    // Note: ListInstancesAsync only returns the first page of results.
    // To request additional pages provide the result.ContinuationToken
    // to the OrchestrationStatusQueryCondition's ContinuationToken property.
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

// Query all orchestration instances
AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(new OrchestrationQuery());

await foreach (OrchestrationMetadata instance in instances)
{
    Console.WriteLine(instance.InstanceId);
}

مثيلات الاستعلام مع عوامل التصفية

ماذا لو لم تكن بحاجة لكل المعلومات التي توفرها استعلام الحالة القياسية؟ على سبيل المثال، ماذا لو كنت تبحث فقط عن وقت إنشاء الأوركسترا أو حالة مدة تشغيل الأوركسترا؟ ضيق نطاق استعلامك بتطبيق فلاتر.

[FunctionName("QueryStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    // Get the first 100 running or pending instances that were created between 7 and 1 days ago
    var queryFilter = new OrchestrationStatusQueryCondition
    {
        RuntimeStatus = new[]
        {
            OrchestrationRuntimeStatus.Pending,
            OrchestrationRuntimeStatus.Running,
        },
        CreatedTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
        CreatedTimeTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
        PageSize = 100,
    };

    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        queryFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

// Get running or pending instances created in the last 7 days
var query = new OrchestrationQuery
{
    Statuses = new[] { OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.Pending },
    CreatedFrom = DateTime.UtcNow.AddDays(-7),
    CreatedTo = DateTime.UtcNow.AddDays(-1),
    PageSize = 100
};

AsyncPageable<OrchestrationMetadata> instances = client.GetAllInstancesAsync(query);

await foreach (OrchestrationMetadata instance in instances)
{
    Console.WriteLine($"{instance.InstanceId}: {instance.RuntimeStatus}");
}

إنهاء المثيلات

إذا كان لديك حالة توزيع موسيقي تستغرق وقتا طويلا للتشغيل، أو تحتاج لإيقافها قبل اكتمالها لأي سبب، يمكنك إنهاؤها.

المعاملتان لواجهة برمجة التطبيقات النهائية هما معرف المثيل وسلسلة السبب ، اللذان يكتبان إلى السجلات وإلى حالة المثيل.

[FunctionName("TerminateInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("terminate-queue")] string instanceId)
{
    string reason = "Found a bug";
    return client.TerminateAsync(instanceId, reason);
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

string reason = "Found a bug";
await client.TerminateInstanceAsync(instanceId, reason);

النسخة المنتهية تنتقل في النهاية إلى Terminated الحالة. لكن هذا الانتقال لا يحدث فورا. بدلا من ذلك، يتم وضع عملية الإنهاء في قائمة الانتظار في مركز المهام مع عمليات أخرى لهذا النموذج. يمكنك استخدام واجهات برمجة تطبيقات استعلام المثيل لمعرفة متى وصل مثيل منتهى Terminated بالفعل إلى الحالة.

ملحوظة

لا يتم نشر إنهاء المثيل حاليا. وظائف النشاط والتنسيقات الفرعية تعمل حتى الاكتمال، بغض النظر عما إذا كنت تنهي نسخة التوزيع التي استدعتها.

تعليق واستئناف الحالات

تعليق التوزيع يسمح لك بإيقاف توزيع موسيقي مستمر. على عكس إنهاء التوزيع الأوركسترالي، يمكنك استئناف التوزيع الموسيقي المعلق لاحقا.

المعلمتان لواجهة برمجة تطبيقات الإيقاف المؤقت هي معرف مثيل وسلسلة سبب، والتي تتم كتابتها إلى السجلات وإلى حالة المثيل.

[FunctionName("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    // To suspend an orchestration
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);

    // To resume an orchestration
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}
using Microsoft.DurableTask.Client;

// To suspend an orchestration
string suspendReason = "Need to pause workflow";
await client.SuspendInstanceAsync(instanceId, suspendReason);

// To resume an orchestration
string resumeReason = "Continue workflow";
await client.ResumeInstanceAsync(instanceId, resumeReason);

تنتقل الحالة المعلقة في النهاية إلى Suspended الولاية. ومع ذلك، هذا الانتقال لا يحدث فورا. بدلا من ذلك، يتم وضع عملية التعليق في قائمة الانتظار في مركز المهام مع العمليات الأخرى في تلك الحالة. استخدم واجهات برمجة تطبيقات استعلام المثيل لمعرفة متى وصل المثيل الجاري فعليا إلى Suspended الحالة.

عند استئناف الموزع المعلق، يتغير حالته مرة أخرى إلى Running.

إرسال الأحداث إلى المثيلات

في بعض السيناريوهات، تحتاج وظائف المنسق إلى الانتظار والاستماع للأحداث الخارجية. من الأمثلة التي يكون فيها هذا النهج مفيدا سيناريوهات المراقبةوالتفاعل البشري .

في بعض السيناريوهات، تحتاج التوزيعات إلى الانتظار والاستماع للأحداث الخارجية. من الأمثلة التي يكون فيها هذا النهج مفيدا سيناريوهات المراقبةوالتفاعل البشري .

يمكنك إرسال إشعارات الأحداث إلى الإصدارات الجارية باستخدام واجهة برمجة تطبيقات Raise Event الخاصة بعميل التنسيق. يمكن للتنسيقات الاستماع إلى هذه الأحداث والاستجابة لها باستخدام انتظار واجهة برمجة تطبيقات منسق الأحداث الخارجية .

المعايير لحدث الرفع هي:

  • معرف المثيل: المعرف الفريد للمثيل.
  • اسم الحدث: اسم الحدث المراد إرساله.
  • بيانات الحدث: حمولة JSON قابلة للتسلسل لإرسالها إلى المثيل.
[FunctionName("RaiseEvent")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("event-queue")] string instanceId)
{
    int[] eventData = new int[] { 1, 2, 3 };
    return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

int[] eventData = new int[] { 1, 2, 3 };
await client.RaiseEventAsync(instanceId, "MyEvent", eventData);

ملحوظة

إذا لم يكن هناك نسخة تنسيق بمعرف النسخة المحدد، يتم تجاهل رسالة الحدث. إذا كان هناك مثيل لكنه لم ينتظر الحدث بعد، يتم تخزين الحدث في حالة النسخة حتى يكون جاهزا للاستلام والمعالجة.

انتظر حتى اكتمال التنسيق

في التوزيعات الموسيقية طويلة الأمد، قد ترغب في الانتظار والحصول على نتائج التوزيع الأوركسترالي. في هذه الحالات، من المفيد أيضا تحديد فترة مهلة على التوزيع الأوركسترالي. إذا تم تجاوز المهلة، يتم إعادة حالة التوزيع بدلا من النتائج.

استخدم واجهة برمجة التطبيقات "انتظر الاكتمال أو إنشاء استجابة حالة المراجعة" للحصول على المخرج الفعلي من مثيل التنسيق بشكل متزامن. افتراضيا، هذه الطريقة لها مهلة زمنية تبلغ عشر ثوان وفترة استطلاع مدتها ثانية واحدة.

إليك مثال على دالة HTTP-trigger التي توضح كيفية استخدام هذه الواجهة:

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace VSSample
{
    public static class HttpSyncStart
    {
        private const string Timeout = "timeout";
        private const string RetryInterval = "retryInterval";

        [FunctionName("HttpSyncStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/wait")]
            HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient 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}'.");

            TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
            TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
            
            return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
                req,
                instanceId,
                timeout,
                retryInterval);
        }

        private static TimeSpan? GetTimeSpan(HttpRequestMessage request, string queryParameterName)
        {
            string queryParameterStringValue = request.RequestUri.ParseQueryString()[queryParameterName];
            if (string.IsNullOrEmpty(queryParameterStringValue))
            {
                return null;
            }

            return TimeSpan.FromSeconds(double.Parse(queryParameterStringValue));
        }
    }
}

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

using Microsoft.DurableTask.Client;

// Wait for orchestration to complete with a timeout
OrchestrationMetadata metadata = await client.WaitForInstanceCompletionAsync(
    instanceId,
    timeout: TimeSpan.FromSeconds(30),
    getInputsAndOutputs: true);

if (metadata.RuntimeStatus == OrchestrationRuntimeStatus.Completed)
{
    Console.WriteLine($"Output: {metadata.SerializedOutput}");
}

استدعاء الدالة مع السطر التالي. استخدم ثانيتين للاستراحة و0.5 ثانية لفترة إعادة المحاولة:

curl -X POST "http://localhost:7071/orchestrators/E1_HelloSequence/wait?timeout=2&retryInterval=0.5"

ملحوظة

يفترض الأمر cURL أعلاه أن لديك دالة منسق تسمى E1_HelloSequence في مشروعك. بسبب كيفية كتابة دالة مشغل HTTP، يمكنك استبدالها باسم أي دالة منسق في مشروعك.

اعتمادا على الوقت اللازم للحصول على الاستجابة من حالة التوزيع الأوركسترالي، هناك حالتان:

  • تنتهي حالات التوزيع ضمن المهلة المحددة (في هذه الحالة ثانيتين)، ويكون الرد هو مخرج مثيل التوزيع الفعلي، الذي يتم تقديمه بشكل متزامن:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:14:29 GMT
Transfer-Encoding: chunked

[
    "Hello Tokyo!",
    "Hello Seattle!",
    "Hello London!"
]
  • لا يمكن لحالات التنسيق أن تنتهي ضمن المهلة المحددة المحددة، والاستجابة هي الافتراضية الموصوفة في اكتشاف رابط رابط API:
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:13:51 GMT
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}
Retry-After: 10
Transfer-Encoding: chunked

{
    "id": "d3b72dddefce4e758d92f4d411567177",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/raiseEvent/{eventName}?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/terminate?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/suspend?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/resume?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}"
}

ملحوظة

قد يختلف تنسيق عناوين webhook حسب النسخة التي تستخدمها من مضيف Azure Functions. المثال السابق هو لمضيف Azure Functions 3.0.

استرداد عناوين URL لخطاف الويب لإدارة HTTP

استخدم نظاما خارجيا لمراقبة أو رفع الأحداث إلى مستوى التنسيق. تتواصل الأنظمة الخارجية مع Durable Functions عبر عناوين webhook التي تشكل جزءا من الاستجابة الافتراضية الموصوفة في <اكتشاف رابط رابط واجهة برمجة التطبيقات <(API) c0>>. يمكن الوصول إلى روابط webhook بشكل برمجي باستخدام ربط عميل التنسيق. تحديدا، تحصل واجهة برمجة تطبيقات إنشاء إدارة HTTP على كائن قابل للتسلسل يحتوي على هذه الروابط الخاصة ب webhook.

تحتوي واجهة برمجة تطبيقات حمولة إدارة HTTP على معلمة واحدة:

  • معرف المثيل: المعرف الفريد للمثيل.

ترجع الأساليب كائنا بخصائص السلسلة التالية:

  • المعرف: معرف المثيل الخاص بالتزامن (يجب أن يكون هو نفس InstanceId الإدخال).
  • StatusQueryGetUri: عنوان URL لحالة مثيل التنسيق.
  • SendEventPostUri: عنوان URL "رفع الحدث" لمثيل التنسيق.
  • TerminatePostUri: عنوان URL "إنهاء" لمثيل التنسيق.
  • PurgeHistoryDeleteUri: عنوان URL "محفوظات التطهير" لمثيل التنسيق.
  • SuspendPostUri: رابط "تعليق" لحالة التوزيع الموسيقي.
  • ResumePostUri: رابط "resume" الخاص بنسخة التوزيع الموسيقي.

ترسل الدوال نسخا من هذه الكائنات إلى أنظمة خارجية لمراقبة أو رفع الأحداث على التنسيقات المقابلة، كما هو موضح في الأمثلة التالية.

[FunctionName("SendInstanceInfo")]
public static void SendInstanceInfo(
    [ActivityTrigger] IDurableActivityContext ctx,
    [DurableClient] IDurableOrchestrationClient client,
    [CosmosDB(
        databaseName: "MonitorDB",
        containerName: "HttpManagementPayloads",
        Connection = "CosmosDBConnectionSetting")]out dynamic document)
{
    HttpManagementPayload payload = client.CreateHttpManagementPayload(ctx.InstanceId);

    // send the payload to Azure Cosmos DB
    document = new { Payload = payload, id = ctx.InstanceId };
}

ملحوظة

الكود السابق في C# يستخدم النموذج قيد العملية مع IDurableOrchestrationClient و IDurableActivityContext، واللذين يتم تصنيفهما كمنقرضين في الإصدارات الأحدث من امتداد Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

إعادة التكرار

إذا حدث فشل في التنسيق لسبب غير متوقع، أعد النسخة إلى حالة سليمة سابقا باستخدام واجهة برمجة تطبيقات مبنية لهذا الغرض.

ملحوظة

هذه الواجهة ليست بديلا عن سياسات معالجة الأخطاء وإعادة المحاولة بشكل صحيح. بل هو مخصص للاستخدام فقط في الحالات التي تفشل فيها حالات التوزيع لأسباب غير متوقعة. لا يمكن "إعادة التوزيع الموسيقية في حالات غير Failed (على سبيل المثال، Running، Pending، Terminated، أو Completed) إلى الوراء. لمزيد من المعلومات حول سياسات معالجة الأخطاء وإعادة المحاولة، راجع مقالة معالجة الأخطاء .

استخدم طريقة (.NET) أو (JavaScript) من طريقة ><ربط عميل التنسيق لإعادة التوزيع إلى حالة Running. تعيد هذه الطريقة أيضا تشغيل فشل تنفيذ النشاط أو التنسيق الفرعي الذي تسبب في فشل التنسيق.

على سبيل المثال، لنفترض أن لديك سير عمل يتضمن سلسلة من الموافقات البشرية. افترض أن سلسلة من وظائف النشاط أبلغت شخصا بأن موافقته مطلوبة وانتظرت حتى الرد في الوقت الحقيقي. بعد أن تتلقى جميع أنشطة الموافقة ردودا أو تتوقف عن الوقت، افترض أن نشاطا آخر فشل بسبب خطأ في تكوين التطبيق، مثل سلسلة connection string غير صالحة. والنتيجة هي فشل التنسيق في عمق سير العمل. مع واجهة برمجة التطبيقات RewindAsync (.NET) أو rewind (JavaScript)، يمكن لمسؤول التطبيق إصلاح خطأ التكوين وإعادة التنسيق الفاشل إلى الحالة التي سبقت الفشل مباشرة. لا يلزم إعادة الموافقة على أي من خطوات التفاعل البشري، ويمكن الآن إكمال التنسيق بنجاح.

ملحوظة

لا تدعم ميزة الإرجاع إرجاع مثيلات التنسيق التي تستخدم مؤقتات دائمة.

[FunctionName("RewindInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("rewind-queue")] string instanceId)
{
    string reason = "Orchestrator failed and needs to be revived.";
    return client.RewindAsync(instanceId, reason);
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

string reason = "Orchestrator failed and needs to be revived.";
await client.RewindInstanceAsync(instanceId, reason);

مثيلات إعادة التشغيل

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

[FunctionName("RestartInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("restart-queue")] string instanceId)
{
    return client.RestartAsync(instanceId, restartWithNewInstanceId: true);
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

// Restart an orchestration with a new instance ID
string newInstanceId = await client.RestartInstanceAsync(instanceId, restartWithNewInstanceId: true);
Console.WriteLine($"Restarted as new instance: {newInstanceId}");

// Restart an orchestration keeping the same instance ID
await client.RestartInstanceAsync(instanceId, restartWithNewInstanceId: false);

إزالة محفوظات المثيل

لإزالة جميع البيانات المرتبطة بتنظيم التشغيل، قم بمسح سجل المشاهد. على سبيل المثال، احذف أي موارد تخزين مرتبطة بمثيل مكتمل. استخدم واجهة برمجة تطبيقات مثيل التطهير التي يحددها عميل التنسيق.

المثال التالي يوضح كيفية تطهير نسخة أوركسترا واحدة.

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("purge-queue")] string instanceId)
{
    return client.PurgeInstanceHistoryAsync(instanceId);
}
using Microsoft.DurableTask.Client;

// Purge a single orchestration instance
PurgeResult result = await client.PurgeInstanceAsync(instanceId);
Console.WriteLine($"Purged {result.PurgedInstanceCount} instance(s).");

المثال التالي يظهر دالة يتم تفعيلها بالمؤقت تقوم بحذف السجل لجميع حالات التوزيع الموسيقي التي اكتملت بعد الفترة الزمنية المحددة. في هذه الحالة، فإنه يزيل البيانات لجميع المثيلات المكتملة منذ 30 يوما أو أكثر. تتم جدولة هذه الدالة على سبيل المثال للتشغيل مرة واحدة يوميا، في الساعة 12:00 مساء بالتوقيت العالمي المتفق عليه:

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
    return client.PurgeInstanceHistoryAsync(
        DateTime.MinValue,
        DateTime.UtcNow.AddDays(-30),  
        new List<OrchestrationStatus>
        {
            OrchestrationStatus.Completed
        });
}

ملحوظة

يستخدم كود C# السابق النموذج قيد العملية مع IDurableOrchestrationClient، والذي يصنف كقديم في الإصدارات الأحدث من إضافة Durable Functions. لمشاريع .NET الجديدة، فكر في استخدام نموذج العامل المعزول .NET مع DurableTaskClient. لمزيد من المعلومات، راجع مقال إصدارات الوظائف المتينة .

using Microsoft.DurableTask.Client;

// Purge completed instances older than 30 days
var filter = new PurgeInstancesFilter(
    CreatedFrom: DateTime.MinValue,
    CreatedTo: DateTime.UtcNow.AddDays(-30),
    Statuses: new[] { OrchestrationRuntimeStatus.Completed });

PurgeResult result = await client.PurgeAllInstancesAsync(filter);
Console.WriteLine($"Purged {result.PurgedInstanceCount} instance(s).");

ملحوظة

لكي تنجح عملية محفوظات الإزالة، يجب أن تكون حالة وقت التشغيل للمثيل الهدف مكتملة أو منتهية أو فاشلة.

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