عملياتنا المعقدة كانت تموت بصمت: كيف أنقذنا ‘منسق سير العمل’ (Workflow Orchestrator) من جحيم الفشل غير المرئي؟

يا جماعة الخير، السلام عليكم ورحمة الله.

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

في البداية، الأمور كانت ماشية “عال العال”. كنا مستخدمين خليط من الـ Cron Jobs على سيرفرات لينكس وشوية سكربتات بايثون بترمي مهام على نظام قائمة انتظار (Queue) بسيط. لكن مع الوقت، كبر النظام، وصارت المشاكل تظهر. المشكلة الكبيرة ما كانت إن العملية بتفشل، المشكلة إنها كانت “بتموت بصمت”. يعني فجأة، نلاقي بيانات المستخدمين مش محدّثة. ليش؟ شو القصة؟ ما حدا عارف. نبدأ رحلة العذاب: نفحص اللوغات (logs) على خمس سيرفرات مختلفة، نكتشف إنه الخطوة رقم 7 “علّقت”، ما أعطت أي خطأ، بس ببساطة توقفت عن العمل. لا إشعار، لا تنبيه، ولا أي حاجة. كأنها تبخرت في الهواء.

صرنا نقضي ساعات كل صباح بس عشان نتأكد إن عملية الليلة الماضية نجحت. وإذا فشلت، بدنا نعيدها يدويًا، ونتأكد إنه ما نعيد الخطوات اللي نجحت عشان ما نعمل بيانات مكررة. الوضع صار جحيم بكل معنى الكلمة. وفي اجتماع صباحي، بعد ليلة قضيناها بنصلّح في مشكلة زي هاي، واحد من الشباب صرخ وقال: “يا جماعة مش معقول هيك! إحنا بنجري ورا أشباح!”. هاي الجملة كانت نقطة التحول. كان لازم نلاقي حل جذري، حل يخرجنا من هذا النفق المظلم. وهنا بدأت رحلتنا مع عالم “منسقات سير العمل” أو الـ Workflow Orchestrators.

ما هو الجحيم الذي كنا نعيش فيه؟ (مشكلة الفشل الصامت)

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

  • الفشل الجزئي (Partial Failures): العملية مكونة من 10 خطوات. الخطوة رقم 6 تفشل. هذا يعني أن أول 5 خطوات تمت بنجاح، لكن النظام الآن في حالة غير متناسقة (inconsistent state). البيانات تم سحبها وتنظيفها، لكن لم يتم تحليلها أو عرضها. كيف نتعامل مع هذا الوضع؟ هل نعيد العملية من الصفر؟
  • المهام المعلّقة (Hanging Jobs): أسوأ أنواع الفشل. السكربت يبدأ، ولكنه لا ينتهي أبدًا ولا يعطي خطأ. يمكن بسبب مشكلة في الشبكة، أو انتظار لمورد خارجي لم يرد أبدًا. بدون نظام مراقبة ذكي، هذه المهمة ستظل “عالقة” إلى الأبد، وتمنع بقية الخطوات من التنفيذ.
  • انعدام الرؤية (Lack of Visibility): لما يكون عندك عدة سكربتات تشتغل على عدة سيرفرات، بصير من المستحيل تعرف الصورة الكاملة. وين وصلت العملية بالضبط؟ أي خطوة فشلت؟ كم مرة حاولنا نعيدها؟ كنا زي اللي بمشي في غرفة معتمة وبتحسس طريقه.
  • صعوبة إعادة المحاولة (Retry Hell): طيب، فشلت خطوة معينة. هل نعيدها فورًا؟ ممكن المشكلة مؤقتة (transient failure). طيب كم مرة نعيدها؟ وشو نعمل إذا فشلت كل المحاولات؟ كتابة منطق إعادة المحاولة (retry logic) لكل خطوة في كل سكربت هو كابوس صيانة وتكرار للكود.

هذا الجحيم هو نتيجة طبيعية لمحاولة إدارة عمليات معقدة وموزعة باستخدام أدوات بسيطة مثل الـ Cron Jobs وقوائم الانتظار فقط. هذه الأدوات ممتازة لمهامها، لكنها لا “تدير حالة” العملية بأكملها.

المنقذ وصل: ما هو ‘منسق سير العمل’ (Workflow Orchestrator)؟

ببساطة شديدة، منسق سير العمل هو “المايسترو” للعمليات الخلفية في نظامك. هو برنامج متخصص وظيفته الأساسية هي تعريف، تنفيذ، ومراقبة سير العمل المكون من عدة خطوات (workflows).

تخيل أنك تبني سيارة على خط إنتاج. كل مرحلة (تركيب المحرك، تركيب العجلات، الدهان) هي “مهمة” (Task). منسق سير العمل هو مدير المصنع الذكي الذي:

  1. يعرف الترتيب الدقيق للخطوات (لا يمكن دهان السيارة قبل تركيب الهيكل).
  2. يُرسل الهيكل إلى محطة المحرك، وعندما تنتهي، يرسله تلقائيًا إلى محطة العجلات.
  3. إذا تعطلت آلة الدهان، فإنه لا يوقف المصنع كله. بل يسجل أن هذه السيارة تنتظر الدهان، ويحاول إرسالها مرة أخرى بعد فترة، أو يرسل تنبيهًا للمهندس المسؤول.
  4. يحتفظ بسجل كامل لكل سيارة: متى دخلت كل محطة، وكم استغرقت، وهل واجهت مشاكل.

هذا هو بالضبط ما يفعله منسق سير العمل للكود الخاص بك. هو يدير الحالة (State)، الترتيب (Sequencing)، الأخطاء (Error Handling)، وإعادة المحاولة (Retries) للعملية بأكملها، مما يحرر المطورين من كتابة كل هذا المنطق المعقد بأنفسهم.

أشهر اللاعبين في الساحة: Airflow vs. Temporal

لما بدأنا نبحث عن حل، كان في اسمين كبار دايماً يظهروا في الساحة: Apache Airflow و Temporal.io. كل واحد منهم له فلسفته وطريقته المختلفة في حل المشكلة.

Apache Airflow: شيخ الكار

Airflow هو الأداة الأقدم والأكثر شهرة في هذا المجال، وهو مشروع مفتوح المصدر تحت مظلة Apache. ممكن نعتبره “شيخ الكار” في عالم أتمتة البيانات.

  • كيف يعمل: الفكرة الأساسية في Airflow هي الـ DAG (Directed Acyclic Graph) أو “الرسم البياني الموجه اللا دوري”. أنت تعرّف سير عملك كملف بايثون يصف المهام والعلاقات بينها (مهمة B تبدأ بعد انتهاء مهمة A).
  • نقاط القوة:
    • واجهة مستخدم غنية: يوفر واجهة ويب ممتازة لمراقبة الـ DAGs، رؤية حالة كل مهمة، إعادة تشغيلها، وعرض السجلات.
    • مجتمع ضخم: كونه الأقدم، فله مجتمع ضخم جدًا، وهذا يعني الكثير من المقالات، الحلول، والإضافات الجاهزة (Providers) للتكامل مع أي خدمة تخطر ببالك تقريبًا (AWS, GCP, قواعد بيانات, …إلخ).
    • مثالي لعمليات الدُفعات (Batch Jobs): ممتاز جدًا للعمليات التي تعمل بجدول زمني محدد (كل ساعة، كل يوم)، مثل عمليات ETL (Extract, Transform, Load).
  • نقاط الضعف:
    • الـ Scheduler: في التصميم التقليدي لـ Airflow، الـ Scheduler هو المسؤول عن جدولة المهام. يمكن أن يصبح هذا عنق زجاجة (bottleneck) وأحيانًا نقطة فشل وحيدة (single point of failure).
    • إدارة الحالة: يعتمد Airflow على قاعدة بيانات خارجية (مثل PostgreSQL) لتخزين حالة كل المهام وسير العمل. هذا يمكن أن يؤدي إلى بطء في الأداء مع عدد كبير جدًا من المهام.
    • ليس مثاليًا للديناميكية: تعريف الـ DAGs ثابت إلى حد ما. من الصعب إنشاء سير عمل ديناميكي يتغير شكله أثناء التنفيذ بناءً على مخرجات خطوة سابقة.

نصيحة أبو عمر: Airflow رائع إذا كانت عملياتك تشبه “الطبخة المجدولة”. لديك وصفة (DAG) واضحة، وتطبخها كل يوم في نفس الوقت. إذا كان معظم عملك هو نقل بيانات وتحويلها بجدول زمني، فـ Airflow خيار صلب ومجرب.

مثال كود بسيط لـ Airflow DAG


from airflow import DAG
from airflow.operators.bash import BashOperator
from datetime import datetime

with DAG(
    dag_id='daily_data_pipeline',
    start_date=datetime(2023, 1, 1),
    schedule_interval='@daily',
    catchup=False
) as dag:
    
    fetch_data = BashOperator(
        task_id='fetch_sales_data',
        bash_command='python /opt/scripts/fetch_data.py'
    )

    process_data = BashOperator(
        task_id='process_sales_data',
        bash_command='python /opt/scripts/process_data.py'
    )

    update_dashboard = BashOperator(
        task_id='update_dashboard',
        bash_command='python /opt/scripts/update_dashboard.py'
    )

    # Defining the order of tasks
    fetch_data >> process_data >> update_dashboard

لاحظ كيف أن الكود يصف “ماذا” يجب أن يحدث و”بأي ترتيب”، و Airflow يتولى التنفيذ والمراقبة.

Temporal.io: الجيل الجديد الواعد

Temporal هو لاعب أحدث في الساحة، لكنه يتبع نهجًا مختلفًا تمامًا. بدلًا من تعريف سير العمل في ملف إعدادات (مثل DAG)، أنت تكتب سير العمل ككود عادي في لغتك المفضلة (Go, Java, Python, TypeScript).

  • كيف يعمل: الفكرة الثورية في Temporal هي “التنفيذ المتين” (Durable Execution). سير العمل (Workflow) الخاص بك هو مجرد دالة (function) طويلة الأمد. عندما تستدعي “مهمة” (Activity) – مثل استدعاء API خارجي – فإن Temporal يحفظ حالة سير العمل بالكامل. إذا انقطع الاتصال، أو مات السيرفر الذي يشغل الكود، أو حتى لو قمت بتحديث الكود، فإن Temporal قادر على استئناف سير العمل من النقطة التي توقف عندها بالضبط، حتى لو كان ذلك بعد أيام أو أسابيع.
  • نقاط القوة:
    • مرونة ومتانة فائقة: سير العمل ينجو من فشل الخوادم، انقطاع الشبكة، وتحديثات التطبيق. هذا يجعله مثاليًا للعمليات الطويلة جدًا (قد تستمر لأشهر) أو العمليات التي تتطلب موثوقية عالية.
    • سير عمل ككود (Workflows as Code): أنت تكتب منطق سير العمل بلغة البرمجة التي تعرفها. هذا يمنحك قوة هائلة للتعبير عن منطق معقد، حلقات تكرار، شروط، ومعالجة أخطاء متقدمة. كل أدواتك المعتادة (testing, debugging) تعمل كما هي.
    • قابلية توسع هائلة (Scalability): تم تصميم Temporal من الألف إلى الياء ليكون نظامًا موزعًا وقابلًا للتوسع الأفقي.
  • نقاط الضعف:
    • منحنى تعلم: الفكرة جديدة على الكثير من المطورين. تحتاج إلى فهم مفاهيم مثل Workflows, Activities, و Deterministic Code.
    • واجهة المستخدم: واجهة المستخدم الافتراضية لـ Temporal وظيفية ولكنها ليست غنية بصريًا مثل واجهة Airflow (على الرغم من أنها تتحسن باستمرار وهناك بدائل).
    • المجتمع: المجتمع أصغر من مجتمع Airflow، لكنه نشط جدًا وسريع النمو.

مثال كود بسيط لسير عمل Temporal (باستخدام Python SDK)


# activities.py (المهام الفعلية)
import requests

async def fetch_data_activity(url: str) -> dict:
    # This is where the actual work happens
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

async def process_data_activity(data: dict) -> dict:
    # Process the data...
    processed_data = {"count": len(data)}
    return processed_data

# workflows.py (المنسق)
from temporalio import workflow
from datetime import timedelta

# Import activities from a different file
with workflow.unsafe.imports_passed_through():
    from . import activities

@workflow.defn
class MyDataWorkflow:
    @workflow.run
    async def run(self, url: str) -> dict:
        # Retry the activity up to 5 times if it fails
        data = await workflow.execute_activity(
            activities.fetch_data_activity,
            url,
            start_to_close_timeout=timedelta(seconds=10),
            retry_policy=workflow.RetryPolicy(maximum_attempts=5)
        )

        processed_result = await workflow.execute_activity(
            activities.process_data_activity,
            data,
            start_to_close_timeout=timedelta(seconds=5),
        )
        
        return processed_result

لاحظ كيف أن منطق إعادة المحاولة (retry_policy) هو جزء من استدعاء المهمة. الكود يبدو ككود بايثون عادي، لكن Temporal يضمن أن هذا الكود “متين” وقابل للاستئناف.

كيف اخترنا الحل المناسب؟ (نصائح أبو عمر)

في قصتنا، بعد دراسة الخيارين، قررنا استخدام Temporal. لماذا؟ لأن طبيعة عملياتنا كانت تتطلب مرونة ومتانة عالية جدًا. لم تكن مجرد عمليات مجدولة، بل كانت هناك عمليات تبدأ بناءً على أحداث المستخدم (user events)، وبعضها كان يستمر لفترات طويلة، والفشل فيها كان مكلفًا جدًا. نهج “سير العمل ككود” أعطانا القوة التي نحتاجها للتعبير عن المنطق المعقد الذي كان لدينا.

لكن هذا لا يعني أن Temporal هو الحل الأفضل للجميع. إليك كيف يمكنك أن تقرر:

  1. حدد طبيعة طبختك: هل عملياتك هي بالأساس عمليات ETL مجدولة؟ هل فريقك مرتاح جدًا مع بايثون والـ SQL؟ قد يكون Airflow خيارًا ممتازًا ومباشرًا.
  2. قياس الألم: هل عملياتك طويلة الأمد؟ هل تحتاج إلى التعامل مع تفاعلات بشرية (مثل انتظار موافقة مدير)؟ هل الفشل الصامت أو فقدان الحالة يكلفك الكثير من المال أو الوقت؟ هنا تتألق قوة ومتانة Temporal.
  3. خبرة الفريق: هل فريقك مكون من مهندسي برمجيات (Software Engineers) يفضلون كتابة الكود واختباره؟ سيشعرون بأنهم في بيتهم مع Temporal. هل فريقك مكون أكثر من محللي بيانات (Data Analysts) ومهندسي بيانات (Data Engineers) يفضلون تعريف خطوط الأنابيب (pipelines)؟ قد يجدون Airflow أسهل للبدء.
  4. لا تخف من التجربة: أفضل نصيحة يمكن أن أقدمها هي أن تبدأ صغيرًا. خذ أكثر عملية مؤلمة ومزعجة لديك، وحاول بناء نسخة مبسطة منها باستخدام كلتا الأداتين. التجربة العملية ستكشف لك أي أداة “تتكلم لغتك” وتناسب عقليتك بشكل أفضل.

النتائج على أرض الواقع: من الفوضى إلى النظام

بعد تطبيق Temporal، تغير الوضع 180 درجة. رحلة العذاب الصباحية انتهت. “رجعنا ننام الليل يا جماعة”.

  • الرؤية الكاملة: أصبح لدينا واجهة تعرض كل عملية نشطة، في أي خطوة هي بالضبط، وكم من الوقت استغرقت، وكل سجلاتها في مكان واحد.
  • المتانة التلقائية: إذا فشلت مهمة بسبب مشكلة مؤقتة في الشبكة، يقوم Temporal بإعادتها تلقائيًا حسب السياسة التي حددناها. إذا مات السيرفر الذي يشغل المهمة، يستأنفها سيرفر آخر من نفس النقطة. السحر!
  • راحة بال المطورين: لم نعد نكتب كودًا مكررًا لإعادة المحاولة وإدارة الحالة. أصبح المطور يركز فقط على كتابة منطق العمل (Business Logic) في الـ Activity، وهو واثق أن “المايسترو” سيهتم بالباقي.

خلاصة الحكي ونصيحة من القلب 💡

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

لا تدع عملياتك المعقدة تموت بصمت في الظلام. سواء اخترت Airflow “شيخ الكار” المجرب، أو Temporal “الجيل الجديد” الواعد، أو أي أداة أخرى، فإن الاستثمار في أتمتة وتنسيق سير عملك هو أفضل استثمار ستقوم به لضمان استقرار نظامك وراحة بالك.

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

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

ادارة الفرق والتنمية البشرية

اجتماعات ما بعد الكارثة: كيف أنقذتنا ثقافة “ما بعد الوفاة الخالية من اللوم” من جحيم الخوف؟

كنّا ندخل اجتماعات ما بعد الخطأ وكأننا في محاكم تفتيش، الكل خائف والكل يلقي باللوم. في هذه المقالة، أشارككم يا جماعة الخير كيف غيرت "ثقافة...

21 أبريل، 2026 قراءة المزيد
اختبارات الاداء والجودة

بيئة الإنتاج كانت حقل ألغام: كيف أنقذتنا ‘هندسة الفوضى’ من جحيم الأعطال غير المتوقعة؟

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

21 أبريل، 2026 قراءة المزيد
نصائح برمجية

إعادة المحاولة كانت كارثة: كيف أنقذتنا ‘العمليات عديمة الأثر’ (Idempotency) من جحيم الآثار الجانبية المزدوجة؟

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

21 أبريل، 2026 قراءة المزيد
​معمارية البرمجيات

خدماتنا كانت تتشابك في فوضى: كيف أنقذتنا ‘المعمارية القائمة على الأحداث’ (EDA) من جحيم الاقتران المحكم؟

أشارككم قصة حقيقية من قلب المعركة البرمجية، كيف انتقلنا من نظام هش ومترابط إلى بنية مرنة وقابلة للتوسع باستخدام المعمارية القائمة على الأحداث (Event-Driven Architecture)....

21 أبريل، 2026 قراءة المزيد
ذكاء اصطناعي

نماذجنا اللغوية كانت عملاقة ومكلفة: كيف أنقذنا ‘تقطير النماذج’ (Model Distillation) من جحيم بطء الاستدلال والتكاليف الباهظة؟

أنا أبو عمر، مبرمج فلسطيني، وأشارككم اليوم قصة حقيقية من تجربتي عن كيفية ترويض نماذج الذكاء الاصطناعي العملاقة. سنغوص في تقنية "تقطير النماذج" (Model Distillation)...

21 أبريل، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

الهياكل العظمية للواجهات (Skeleton Screens): كيف أنقذت مشروعي من جحيم شاشات التحميل؟

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

21 أبريل، 2026 قراءة المزيد
البودكاست