إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
ابن تطبيقات ذات حالة مع Durable Functions. إنه امتداد ل Azure Functions. استخدم orchestrator function لتنسيق Durable Functions الأخرى في تطبيق الوظيفة الخاص بك. وظائف الأوركستراتور موثوقة وموثوقة، وهي مصممة لتعمل لفترة طويلة.
قم ببناء سير عمل تتحمل الحالة والأخطاء باستخدام SDKs Trials Task في .NET وPython وJava. استخدم منسقا لتنسيق الأنشطة والتوزيع الفرعي. المنظمون موثوقون وموثوقون ومصممون لتشغيل لفترة طويلة.
قيود كود الأوركستراتور
تستخدم وظائف المنسق مصدر الأحداث لضمان التنفيذ الموثوق والحفاظ على حالة المتغيرة المحلية. سلوك إعادة التشغيل في كود الأوركستراتور يخلق قيودا على نوع الكود الذي يمكنك كتابته في دالة الأوركستراتور. على سبيل المثال، يجب أن تكون وظائف الأوركستراتور حتمية: حيث تعيد دالة الأوركستراتور تشغيل عدة مرات، ويجب أن تنتج نفس النتيجة في كل مرة.
يستخدم المنسقون مصادر الأحداث لضمان التنفيذ الموثوق والحفاظ على الحالة المتغيرة المحلية. سلوك إعادة التشغيل في كود الأوركستراتور يخلق قيودا على نوع الكود الذي يمكنك كتابته في الأوركستراتور. على سبيل المثال، يجب أن يكون المنظمون حتميين: حيث يعيد الموزع تشغيل عدة مرات، ويجب أن ينتج نفس النتيجة في كل مرة.
استخدم واجهات برمجة التطبيقات الحتمية
إليك بعض الإرشادات البسيطة لضمان أن الكود الخاص بك حتمي.
استدعي واجهات برمجة التطبيقات من لغاتك المستهدفة في دوال التنسيق، لكن استخدم فقط واجهات برمجة التطبيقات الحتمية. واجهة برمجة التطبيقات الحتمية دائما ترجع نفس القيمة لنفس المدخل، بغض النظر عن وقت أو عدد مرات استدعاؤها.
الأقسام التالية تقدم إرشادات حول واجهات برمجة التطبيقات والأنماط التي يجب تجنبها لأنها ليست حتمية. تنطبق هذه القيود فقط على وظائف الموزعين. أنواع الوظائف الأخرى لا تفرض مثل هذه القيود.
إليك بعض الإرشادات البسيطة لضمان أن الكود الخاص بك حتمي.
استدعي واجهات برمجة التطبيقات من لغاتك المستهدفة في المنظمات، لكن استخدم فقط واجهات برمجة التطبيقات الحتمية. واجهة برمجة التطبيقات الحتمية دائما ترجع نفس القيمة لنفس المدخل، بغض النظر عن وقت أو عدد مرات استدعاؤها.
الأقسام التالية تقدم إرشادات حول واجهات برمجة التطبيقات والأنماط التي يجب تجنبها لأنها ليست حتمية. تنطبق هذه القيود فقط على الموزعين. الأنشطة لا تخضع لمثل هذه القيود.
ملحوظة
تغطي هذه المقالة القيود الشائعة على كود الأوركستراتور، لكنها ليست شاملة. ركز على ما إذا كانت واجهة برمجة التطبيقات حتمية. بهذه العقلية، يمكنك عادة معرفة أي واجهات برمجة التطبيقات آمنة للاستخدام دون الرجوع إلى هذه القائمة.
التواريخ والأوقات
واجهات برمجة التطبيقات القائمة على الوقت غير حتمية ولا ينبغي استخدامها أبدا في وظائف التنسيق. كل إعادة تشغيل وظيفة التنسيق تنتج قيمة مختلفة. بدلا من ذلك، استخدم واجهة برمجة التطبيقات المعادلة ل Durable Functions للحصول على التاريخ أو الوقت الحالي، والذي يظل ثابتا عبر الإعادات.
لا تستخدم DateTime.Now، DateTime.UtcNowأو واجهات برمجة التطبيقات المعادلة للحصول على الوقت الحالي. يجب أيضا تجنب مثل هذه المواد Stopwatch . بالنسبة .NET وظائف التنسيق أثناء العملية، استخدم خاصية IDurableOrchestrationContext.CurrentUtcDateTime للحصول على الوقت الحالي. بالنسبة .NET وظائف التنسيق المعزولة، استخدم خاصية TaskOrchestrationContext.CurrentDateTimeUtc للحصول على الوقت الحالي.
DateTime startTime = context.CurrentUtcDateTime;
// do some work
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);
واجهات برمجة التطبيقات القائمة على الوقت غير حتمية ولا ينبغي استخدامها أبدا في المنظمين. كل إعادة تشغيل من قبل الأوركستراتور تنتج قيمة مختلفة. بدلا من ذلك، استخدم واجهة برمجة التطبيقات المكافئة ل Durable Task SDK للحصول على التاريخ أو الوقت الحالي، والذي يظل ثابتا عبر الإعادات.
لا تستخدم DateTime.Now، DateTime.UtcNowأو واجهات برمجة التطبيقات المعادلة للحصول على الوقت الحالي. يجب أيضا تجنب مثل هذه المواد Stopwatch . استخدم العقار TaskOrchestrationContext.CurrentUtcDateTime للحصول على الوقت الحالي.
using Microsoft.DurableTask;
public class TimerExample : TaskOrchestrator<object?, TimeSpan>
{
public override async Task<TimeSpan> RunAsync(TaskOrchestrationContext context, object? input)
{
// Use context.CurrentUtcDateTime instead of DateTime.Now or DateTime.UtcNow
DateTime startTime = context.CurrentUtcDateTime;
// do some work
await context.CallActivityAsync("DoWork", null);
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);
return totalTime;
}
}
الواجهات الرسومية وUUIDs
واجهات برمجة التطبيقات التي تعيد واجهة المستخدم الرسومية العشوائية أو UUID غير حتمية لأن القيمة المولدة تختلف مع كل إعادة تشغيل. اعتمادا على لغتك، قد تتوفر واجهة برمجة تطبيقات مدمجة لإنشاء GUIDs أو UUIDs حتمية. وإلا، استخدم دالة نشاط لإرجاع معرف المستخدم (GUID) أو UUID المولد عشوائيا.
بدلا من واجهات برمجة التطبيقات مثل Guid.NewGuid()، استخدم واجهة برمجة تطبيقات كائن NewGuid() السياق لإنشاء واجهة مستخدم عشوائية آمنة لإعادة تشغيل المنظم.
Guid randomGuid = context.NewGuid();
ملحوظة
واجهات المستخدم الرسومية المولدة باستخدام واجهات برمجة تطبيقات سياق التنسيق هي UUIDs من النوع 5.
واجهات برمجة التطبيقات التي تعيد واجهة المستخدم الرسومية العشوائية أو UUID غير حتمية لأن القيمة المولدة تختلف مع كل إعادة تشغيل. اعتمادا على لغتك، قد تتوفر واجهة برمجة تطبيقات مدمجة لإنشاء GUIDs أو UUIDs حتمية. وإلا، استخدم نشاطا لإرجاع معرف GUID أو UUID تم توليدها عشوائيا.
بدلا من واجهات برمجة التطبيقات مثل Guid.NewGuid()، استخدم واجهة برمجة تطبيقات كائن NewGuid() السياق لإنشاء واجهة مستخدم عشوائية آمنة لإعادة تشغيل المنظم.
using Microsoft.DurableTask;
public class GuidExample : TaskOrchestrator<object?, Guid>
{
public override async Task<Guid> RunAsync(TaskOrchestrationContext context, object? input)
{
// Use context.NewGuid() instead of Guid.NewGuid()
Guid randomGuid = context.NewGuid();
return randomGuid;
}
}
ملحوظة
واجهات المستخدم الرسومية المولدة باستخدام واجهات برمجة تطبيقات سياق التنسيق هي UUIDs من النوع 5.
أرقام عشوائية
استخدم دالة نشاط لإرجاع أرقام عشوائية إلى دالة المنظم. قيم العودة لوظائف النشاط دائما آمنة لإعادة التشغيل لأنها تحفظ في سجل التوزيع الأوركسترالي.
بدلا من ذلك، يمكنك استخدام مولد أرقام عشوائية بقيمة بذور ثابتة مباشرة في دالة الأوركستراتور. هذا النهج آمن طالما يتم توليد نفس تسلسل الأرقام في كل إعادة توزيع أوركسترالي.
استخدم نشاطا لإعادة أرقام عشوائية إلى الموزع. قيم العودة للأنشطة دائما آمنة لإعادة التشغيل لأنها تحفظ في تاريخ التوزيع الموسيقي.
بدلا من ذلك، يمكنك استخدام مولد أرقام عشوائية بقيمة بذرة ثابتة مباشرة في الأوركستراتور. هذا النهج آمن طالما يتم توليد نفس تسلسل الأرقام في كل إعادة توزيع أوركسترالي.
Bindings
لا تستخدم الروابط في وظيفة الأوركستراتور، بما في ذلك ربط عميل التنسيقوربط عميل الكيان . استخدم ربطات الإدخال والإخراج فقط في دالة العميل أو النشاط. يمكن لوظائف الأوركستراتور إعادة التشغيل عدة مرات، مما يسبب إدخال/إخراج غير حتمية ومكررة مع أنظمة خارجية.
يجب ألا يقوم المنظمون بعمليات إدخال/إخراج مباشرة مع أنظمة خارجية. نقل عمليات الإدخال/الإخراج إلى الأنشطة. يمكن للمنسقين إعادة التشغيل عدة مرات، مما يسبب إدخال/إخراج غير حتمية ومكررة مع أنظمة خارجية.
المتغيرات الثابتة
يمكن أن تتغير المتغيرات الثابتة مع مرور الوقت، مما يجعلها غير آمنة لوظائف المنسق. تجنب استخدام المتغيرات الثابتة في دوال التنسيق لأن قيمها قد تتغير مع مرور الوقت، مما يؤدي إلى سلوك تشغيل غير حتمي. بدلا من ذلك، استخدم الثوابع، أو اقتصر استخدام المتغيرات الثابتة على دوال النشاط فقط.
المتغيرات الثابتة يمكن أن تتغير مع الوقت، مما يجعلها غير آمنة للمنظمين. تجنب استخدام المتغيرات الثابتة في المنظمين لأن قيمها قد تتغير مع مرور الوقت، مما يؤدي إلى سلوك تشغيل غير حتمي. بدلا من ذلك، استخدم الثواب، أو اقتصر استخدام المتغيرات الثابتة على الأنشطة.
ملحوظة
حتى خارج وظائف المنسق، استخدام المتغيرات الثابتة في Azure Functions قد يكون مشكلة لأسباب مختلفة لأنه لا يوجد ضمان باستمرار الحالة الثابتة عبر عدة عمليات تنفيذ للوظائف. تجنب المتغيرات الثابتة إلا في حالات استخدام محددة، مثل التخزين المؤقت بأفضل جهد في الذاكرة في دوال النشاط أو الكيانات.
متغيرات البيئة
يمكن أن تتغير متغيرات البيئة في وظائف الأوركستراتور مع مرور الوقت، مما يؤدي إلى سلوك تشغيل غير حتمي. إذا كانت دالة المنسق تحتاج إلى تكوين محدد في متغير البيئة، يجب عليك تمرير قيمة التكوين إلى دالة المنسق كمدخل أو كقيمة عودة لدالة نشاط.
يمكن أن تتغير متغيرات البيئة في المنظمين مع مرور الوقت، مما يؤدي إلى سلوك تشغيل غير حتمي. إذا كان المنسق يحتاج إلى تكوين محدد في متغير بيئتي، يجب عليك تمرير قيمة التكوين إلى المنسق كمدخل أو كقيمة إرجاع لنشاط.
الشبكة وHTTP
استخدم وظائف النشاط لإجراء مكالمات الشبكة الصادرة. إذا كنت بحاجة لإجراء استدعاء HTTP من وظيفة التنسيق الخاص بك، يمكنك أيضا استخدام واجهات برمجة تطبيقات HTTP المتينة.
استخدم الأنشطة لإجراء مكالمات الشبكة الصادرة. يجب ألا يقوم المنسقون أبدا بإجراء مكالمات HTTP مباشرة أو طلبات شبكة أخرى لأن هذه العمليات غير حتمية.
واجهات برمجة التطبيقات التي تحجب الخيوط
حجب واجهات برمجة التطبيقات مثل sleep يمكن أن يسبب مشاكل في الأداء والمقياس لوظائف المنسق، وقد يؤدي إلى تكاليف زمن تنفيذ غير ضرورية في خطة استهلاك Azure Functions. استخدم البدائل عندما تكون متاحة. على سبيل المثال، استخدم مؤقتات Durable لإنشاء تأخيرات آمنة لإعادة التشغيل ولا تحتسب ضمن وقت تنفيذ المنظم.
حظر واجهات برمجة التطبيقات مثل "السكون" يمكن أن يسبب مشاكل في الأداء والمقياس للمنسقين ويجب تجنبه. استخدم مؤقتات متينة لخلق تأخيرات آمنة لإعادة اللعب.
استخدم context.CreateTimer() بدلا من Task.Delay() أو Thread.Sleep().
// Don't use Task.Delay() or Thread.Sleep()
// Use context.CreateTimer() instead
await context.CreateTimer(context.CurrentUtcDateTime.AddMinutes(5), CancellationToken.None);
واجهات برمجة التطبيقات غير المتزامنة
يجب ألا يبدأ كود المنسق أي عملية غير متزامنة أبدا، باستثناء العمليات التي يحددها كائن السياق الخاص بمشغل التنسيق. على سبيل المثال، لا تستخدم أبدا Task.Run، Task.Delay، و HttpClient.SendAsync في .NET أو setTimeout و setInterval في JavaScript. يجب أن تقوم وظيفة التنسيق بجدولة الأعمال غير المتزامنة فقط باستخدام واجهات برمجة تطبيقات Durable SDK، مثل دوال جدولة النشاط. أي نوع آخر من الاستدعاءات غير المتزامنة يجب أن يتم داخل دوال النشاط.
يجب ألا يبدأ كود المنسق أي عملية غير متزامنة أبدا، باستثناء العمليات التي يحددها كائن سياق التنسيق. على سبيل المثال، لا تستخدم أبدا Task.Run، Task.Delay، و HttpClient.SendAsync في .NET. يجب على المنسق جدولة الأعمال غير المتزامنة فقط باستخدام واجهات برمجة تطبيقات SDK لمهام Durable، مثل جدولة الأنشطة. أي نوع آخر من الاستدعاءات غير المتزامنة يجب أن يتم داخل الأنشطة.
وظائف جافاسكريبت غير المتزامنة
إعلان وظائف التنسيق في JavaScript كدوال مولد متزامنة. لا تعلن وظائف التنسيق في JavaScript لأن async وقت التشغيل Node.js لا يضمن سلوكا حتميا للوظائف async .
الروتينات التكرارية في Python
لا تعلن أن دوال Python orchestrator هي coroutines. لا تستخدم كلمة async المفتاحية لأن دلالات الكوروتينات لا تتوافق مع نموذج إعادة التشغيل Durable Functions. أعلن عن Python يعمل كمولد، واستخدم yield بدلا من await مع واجهة برمجة التطبيقات context.
يجب ألا تعلن أن أوركستراتورات Python هي coroutines. بمعنى آخر، لا تعلن أبدا عن Python المنظمين باستخدام الكلمة المفتاحية async لأن دلالات الكوروتينات لا تتوافق مع نموذج إعادة تشغيل المهام المتطورة. يجب عليك دائما إعلان Python المنظمين كمولدين، مما يعني أنه يجب عليك استخدام yield بدلا من await عند استدعاء واجهات برمجة التطبيقات للسياق.
from durabletask import task
# CORRECT - use yield (generator function)
def my_orchestrator(ctx: task.OrchestrationContext, input: str):
result = yield ctx.call_activity(my_activity, input=input)
return result
# WRONG - don't use async/await
async def bad_orchestrator(ctx: task.OrchestrationContext, input: str):
result = await ctx.call_activity(my_activity, input=input) # This won't work!
return result
واجهات برمجة تطبيقات .NET للخيوط
إطار عمل المهام الدائم يشغل كود المنسق على خيط واحد ولا يمكنه التفاعل مع أي خيوط أخرى. تشغيل استمرارات غير متزامنة على خيط تجمع العمال في تنفيذ التوزيع قد يؤدي إلى تنفيذ غير حتمي أو جمود. لهذا السبب، يجب ألا تستخدم وظائف التنسيق تقريبا واجهات برمجة تطبيقات الخيوط. على سبيل المثال، لا تستخدمها ConfigureAwait(continueOnCapturedContext: false) أبدا في دالة الأوركستراتور لضمان استمرار المهام على وظيفة الأوركستراتور الأصلية SynchronizationContext.
ملحوظة
يحاول إطار عمل المهام الدائمة اكتشاف الاستخدام العرضي للخيوط غير المنسقة في وظائف الأوركستراتور. إذا وجد انتهاكا، يقوم الإطار بفرض استثناء NonDeterministicOrchestrationException . ومع ذلك، هذا السلوك في الكشف لن يكتشف جميع الانتهاكات، ولا ينبغي أن تعتمد عليه.
إطار عمل المهام الدائم يشغل كود المنسق على خيط واحد ولا يمكنه التفاعل مع أي خيوط أخرى. تشغيل استمرارات غير متزامنة على خيط تجمع العمال في تنفيذ التوزيع قد يؤدي إلى تنفيذ غير حتمي أو جمود. لهذا السبب، يجب على المنسقين تقريبا ألا يستخدموا واجهات برمجة تطبيقات الخيوط. على سبيل المثال، لا تستخدمها ConfigureAwait(continueOnCapturedContext: false) أبدا في الأوركستراتور لضمان استمرار المهام على الأصل SynchronizationContextالخاص ب .
ملحوظة
يحاول إطار العمل الدائم للعمل اكتشاف الاستخدام العرضي للخيوط غير المنسقة في الأوركستراتور. إذا وجد انتهاكا، يقوم الإطار بفرض استثناء NonDeterministicOrchestrationException . ومع ذلك، هذا السلوك في الكشف لن يكتشف جميع الانتهاكات، ولا ينبغي أن تعتمد عليه.
إدارة الإصدارات
يمكن أن تستمر التوزيع الموسيقي المتين لأيام، شهور، سنوات، أو حتى كأوركسترا أبدية. تغييرات الكود التي تؤثر على تشغيل التنسيقات يمكن أن تكسر سلوك إعادة التشغيل، لذا خطط جيدا قبل تحديث تطبيقك. لمزيد من المعلومات، راجع الإصدارات.
يمكن أن تستمر التوزيع الموسيقي الدائم لأيام أو شهور أو سنوات أو حتى إلى أجل غير مسمى. تغييرات الكود التي تؤثر على تشغيل التنسيقات يمكن أن تكسر سلوك إعادة التشغيل، لذا خطط جيدا قبل تحديث تطبيقك. تشمل استراتيجيات الإصدار الشائعة النشر جنبا إلى جنب واستخدام أسماء مراكز المهام الخاصة بالإصدارات.
المهام الدائمة
ملحوظة
يصف هذا القسم تفاصيل التنفيذ الداخلية لإطار العمل الدائم للمهام. لا تحتاج إلى معرفة هذه المعلومات لاستخدام Durable Functions، لكنها تساعد في تفسير سلوك إعادة التشغيل.
المهام التي يمكن الانتظار بأمان في وظائف التنسيق تسمى أحيانا مهام دائمة. إطار العمل للمهام الدائمة ينشئ ويدير هذه المهام. تشمل الأمثلة المهام التي أعيدت بواسطة CallActivityAsync، WaitForExternalEvent، و CreateTimer في وظائف التنسيق .NET.
قائمة بكائنات TaskCompletionSource في .NET تدير هذه المهام المتطورة داخليا. أثناء إعادة التشغيل، يقوم كود الموزع بإنشاء هذه المهام. يكمل الموزع هذه الأحداث أثناء عدد الأحداث التاريخية المقابلة.
ينفذ وقت التشغيل المهام بشكل متزامن على خيط واحد حتى يعيد تشغيل التاريخ. إذا لم تنته مهمة دائمة بحلول نهاية إعادة التاريخ، فإن مدة التشغيل تتخذ الإجراءات المناسبة. على سبيل المثال، يمكن لوقت التشغيل أن يدخل رسالة لاستدعاء دالة نشاط.
هذا السلوك في وقت التشغيل يفسر لماذا لا يمكن لوظيفة المنسق استخدام await أو yield في مهمة غير دائمة. لا يستطيع خيط الموزع الانتظار حتى تنتهي المهمة، ويمكن أن تؤدي الاستدعاءات من تلك المهمة إلى تلف حالة تتبع وظيفة المنسق. يتضمن وقت التشغيل فحوصات للمساعدة في اكتشاف هذه الانتهاكات.
لمعرفة المزيد عن كيفية تنفيذ إطار عمل المهام المتطورة لوظائف التنسيق، راجع الشيفرة المصدرية Durable Task على GitHub. على وجه الخصوص، انظر TaskOrchestrationExecutor.cs و TaskOrchestrationContext.cs.
المهام التي يمكن الانتظار بأمان في المنظمين تسمى أحيانا مهام متينة. إطار العمل للمهام الدائمة ينشئ ويدير هذه المهام. تشمل الأمثلة المهام التي يعيدها CallActivityAsync، WaitForExternalEvent، وCreateTimer في .NET المنظمين.
قائمة بكائنات TaskCompletionSource في .NET تدير هذه المهام المتطورة داخليا. أثناء إعادة التشغيل، يقوم كود الموزع بإنشاء هذه المهام. يكمل الموزع هذه الأحداث أثناء عدد الأحداث التاريخية المقابلة.
ينفذ وقت التشغيل المهام بشكل متزامن على خيط واحد حتى يعيد تشغيل التاريخ. إذا لم تنته مهمة دائمة بحلول نهاية إعادة التاريخ، فإن مدة التشغيل تتخذ الإجراءات المناسبة. على سبيل المثال، يمكن لوقت التشغيل أن يدخل رسالة لاستدعاء نشاط.
هذا السلوك في وقت التشغيل يفسر لماذا لا يستطيع المنسق استخدام await أو yield في مهمة غير متينة. لا يمكن لسلسلة المرسل الانتظار حتى تنتهي المهمة، ويمكن أن تؤدي الاستدعاءات من تلك المهمة إلى تلف حالة تتبع المنسق. يتضمن وقت التشغيل فحوصات للمساعدة في اكتشاف هذه الانتهاكات.
لمعرفة المزيد عن كيفية تنفيذ إطار المهام المتطورة للمنظمين، راجع الشفرة المصدرية Durable Task على GitHub. على وجه الخصوص، انظر TaskOrchestrationExecutor.cs و TaskOrchestrationContext.cs.