أوضاع تنفيذ سير العمل

عند تشغيل سير عمل في .NET، يتحكم وضع التنفيذ في كيفية معالجة العمليات الفائقة وكيفية تسليم الأحداث إلى المستهلك. InProcessExecution تعرض الفئة وضعي تنفيذ: OffThread و Lockstep.

نظرة عامة

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

OffThread

OffThread هو وضع التنفيذ الافتراضي . تعمل عمليات التراكب على مؤشر ترابط خلفية، وتتدفق الأحداث على الفور كما يتم رفعها عبر تنفيذ قائم على القناة.

// OffThread is the default — these are equivalent:
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input);
await using StreamingRun run = await InProcessExecution.OffThread.RunStreamingAsync(workflow, input);

كيف يعمل

  1. يتم تشغيل مهمة في الخلفية بشكل مستمر أثناء تعليق الرسائل.
  2. نظرا لأن المنفذين ينتجون مخرجات أو أحداثا، تتم كتابة الكائنات الناتجة WorkflowEvent إلى غير مقيد.Channel<WorkflowEvent>
  3. يقرأ المستهلك الأحداث من القناة عبر WatchStreamAsync، ويستقبلها في الوقت الحقيقي أثناء إنتاجها.
  4. عند اكتمال جميع عمليات التراكب وعدم الاحتفاظ بأي رسائل، يتوقف التشغيل بحالة Idle أو PendingRequests .

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

عمليات التشغيل المتزامنة

يدعم OffThread أيضا متغيرا متزامنا يسمح بتشغيلات متعددة لمشاركة نفس مثيل سير العمل في وقت واحد:

await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(workflow, input);

Important

يتطلب التنفيذ المتزامن الإعلان عن crossRunShareable جميع المنفذين في سير العمل (على الدالة الإنشائية) أو توفيرها كأساليب المصنع.

خط التأمين

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

await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);

كيف يعمل

  1. يستدعي WatchStreamAsyncالمستهلك ، الذي يدفع حلقة التنفيذ.
  2. يتم تشغيل فائقة حتى الاكتمال، ويتم تجميع الأحداث في قائمة انتظار.
  3. بعد انتهاء الفوقية، يتم إرجاع جميع الأحداث في قائمة الانتظار إلى المستهلك.
  4. تبدأ الخطوة الفائقة التالية فقط بعد أن يتلقى المستهلك جميع الأحداث من الحدث السابق.

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

متى تستخدم Lockstep

يعد Lockstep مفيدا عندما:

  • الاختبار — يجعل ترتيب الأحداث المحدد التأكيدات مباشرة.
  • تصحيح الأخطاء — يكون تصحيح الأخطاء خطوة بخطوة أسهل عندما يبقى التنفيذ على مؤشر ترابط المستهلك.
  • المعالجة مرتبة — السيناريوهات التي تحتاج فيها إلى معالجة أحداث فائقة بشكل كامل قبل بدء الخطوة الفائقة التالية.

اختيار وضع التنفيذ

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

استخدم Lockstep عندما يكون السلوك المحدد أكثر أهمية من الأداء، كما هو الحال في اختبارات الوحدة أو جلسات تصحيح الأخطاء.

// Production: OffThread (default)
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input);

// Testing: Lockstep for deterministic behavior
await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);

التنفيذ غير المتدفق

يدعم كلا وضعي التنفيذ التنفيذ غير المتدفق عبر RunAsync. في الوضع غير المتدفق، يتم تشغيل سير العمل حتى الاكتمال ويجمع جميع الأحداث في كائن Run بدلا من دفقها بشكل متزايد:

Run run = await InProcessExecution.RunAsync(workflow, input);

// Access all emitted events
foreach (WorkflowEvent evt in run.OutgoingEvents)
{
    // Process events
}

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

يستخدم التنفيذ غير المتدفق وضع OffThread الافتراضي. لاستخدام Lockstep مع التنفيذ غير المتدفق:

Run run = await InProcessExecution.Lockstep.RunAsync(workflow, input);

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

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

للحصول على معلومات حول تشغيل مهام سير العمل Python، راجع منشئ سير العمل التنفيذ.

عند تشغيل سير عمل في Go، تتحكم بيئة التنفيذ في كيفية معالجة عمليات التراكب وكيفية تسليم الأحداث إلى المستهلك. workflow/inproc تعرض الحزمة ثلاث بيئات: DefaultOffThread/و Lockstepو.Concurrent

نظرة عامة

OffThread / افتراضي خط التأمين Concurrent
تنفيذ الفوقية goroutine في الخلفية مدفوع من قبل مستهلك الحدث goroutine في الخلفية
تسليم الحدث فوري، حيث يتم رفع الأحداث يتم دفعها أثناء استهلاك الدفق فوري، حيث يتم رفع الأحداث
الأفضل ل الدفق في الوقت الحقيقي، سيناريوهات الإنتاج الاختبار، وتصحيح الأخطاء، وترتيب محدد مثيلات سير العمل المشتركة مع روابط آمنة متزامنة

OffThread

OffThread هو وضع التنفيذ الافتراضي. هذه مكافئة:

stream, err := inproc.Default.RunStreaming(ctx, wf, input)
stream, err := inproc.OffThread.RunStreaming(ctx, wf, input)

كيف يعمل

  1. يقوم goroutine في الخلفية بتشغيل عمليات فائقة أثناء تعليق الرسائل.
  2. نظرا لأن المنفذين ينتجون مخرجات أو أحداثا، تتم كتابة أحداث سير العمل إلى الدفق.
  3. يقرأ المستهلك الأحداث مع WatchStream، ويستقبلها أثناء إنتاجها.
  4. عند اكتمال جميع عمليات التراكب وعدم الاحتفاظ بأي رسائل، يتوقف التشغيل بحالة الخمول أو الطلب المعلق.

عمليات التشغيل المتزامنة

استخدم inproc.Concurrent عندما تدعم كافة روابط المنفذ في سير العمل التنفيذ المشترك المتزامن:

stream, err := inproc.Concurrent.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer stream.Close(ctx)

خط التأمين

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

stream, err := inproc.Lockstep.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer stream.Close(ctx)

for evt, err := range stream.WatchStream(ctx) {
    if err != nil {
        return err
    }
    // inspect event
}

كيف يعمل

  1. يستدعي WatchStreamالمستهلك ، الذي يدفع حلقة التنفيذ.
  2. يتم تشغيل الخرافة حتى الاكتمال ويتم تجميع الأحداث.
  3. يتم إرجاع الأحداث المتراكمة للمستهلك.
  4. تبدأ الخطوة الفائقة التالية فقط بعد أن يتلقى المستهلك أحداث الخطوة الفائقة السابقة.

متى تستخدم Lockstep

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

اختيار وضع التنفيذ

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

// Production: OffThread (default)
stream, err := inproc.Default.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer stream.Close(ctx)

// Testing: Lockstep for deterministic behavior
testStream, err := inproc.Lockstep.RunStreaming(ctx, wf, input)
if err != nil {
    return err
}
defer testStream.Close(ctx)

التنفيذ غير المتدفق

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

run, err := inproc.Default.Run(ctx, wf, input)
if err != nil {
    return err
}

for evt := range run.NewEvents() {
    if output, ok := evt.(workflow.OutputEvent); ok {
        fmt.Printf("Final result: %v\n", output.Output)
    }
}

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