من كوابيس الحالة المفقودة إلى الأتمتة المنظمة: كيف أنقذتنا محركات سير العمل (Workflow Engines)؟

السلام عليكم يا جماعة الخير، معكم أخوكم أبو عمر.

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

في البداية، قلنا “الموضوع بسيط”. عملنا جدول في قاعدة البيانات اسمه funding_requests وحطينا فيه عمود اسمه status. مع كل مرحلة، بنحدّث الحالة. أول طلبين ثلاثة مشيوا تمام. لكن لما زاد الضغط، بلشت المصايب. خدمة التحقق من الأهلية بتعلق، بس خدمة تقديم الطلب بتكون سجلت إنه “قيد التحقق”. طيب شو الحل؟ نرجعها يدوي؟ وإذا خدمة صرف المبلغ فشلت بعد ما تسجلت الموافقة النهائية؟ المصاري ما طلعت، بس النظام بقول “تم الصرف”! صرنا نقضي ساعات كل يوم نصلح “حالات” طلبات عالقة يدويًا. كانت “عجقة” ما بعدها عجقة، والواحد يروح على الدار وهو شايل هم طلبات العملاء اللي ضاعت في متاهة النظام. كنت أحكي لزملائي: “يا زلمة، إحنا مش مبرمجين، إحنا صرنا محققين في جرائم الحالة المفقودة!”.

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

المشكلة الحقيقية: جحيم الحالة المفقودة في الأنظمة الموزعة

المشكلة التي واجهناها لها اسم تقني معروف: إدارة الحالة وتنسيق العمليات (State Management and Orchestration) في الأنظمة الموزعة. عندما تكون العملية طويلة الأمد وتتضمن خطوات متعددة تنفذها خدمات مستقلة، تظهر تحديات هائلة:

  • ضياع الحالة (Lost State): إذا فشلت خدمة في منتصف الطريق، أين تكمن “الحقيقة”؟ هل هي في قاعدة بيانات الخدمة الأولى أم الثانية؟
  • الرؤية والمراقبة (Visibility & Monitoring): من المستحيل تقريبًا معرفة أين تقف كل عملية من آلاف العمليات الجارية بمجرد النظر إلى قواعد بيانات متفرقة. أنت بحاجة إلى لوحة تحكم مركزية.
  • التعامل مع الأخطاء (Error Handling): ماذا لو فشلت خطوة ما؟ هل يجب إعادة المحاولة (Retry)؟ كم مرة؟ وماذا لو فشلت كل المحاولات؟ هل يجب إلغاء العملية بأكملها وتعويض الخطوات السابقة (Compensation)؟ كتابة هذا المنطق داخل كل خدمة يجعل الكود معقدًا وهشًا.
  • صعوبة التعديل: ماذا لو أراد قسم الأعمال إضافة خطوة جديدة (مثل “موافقة إضافية”)؟ هذا يعني تغيير الكود في عدة خدمات، وإعادة نشرها، ومواجهة خطر إدخال أخطاء جديدة.

الطريقة التقليدية الفاشلة: عمود “الحالة”

محاولتنا الأولى، وهي استخدام عمود status في قاعدة البيانات، هي فخ يقع فيه الكثيرون. تبدو بسيطة في البداية، ولكنها تتحول إلى كابوس للأسباب التالية:

  • منطق التنسيق يتسرب إلى الخدمات: كل خدمة تحتاج أن تعرف ما هي الخطوة التالية، مما يخلق اقترانًا شديدًا (Tight Coupling) بينها.
  • لا يوجد سجل تاريخي واضح: أنت تعرف الحالة الحالية، لكن من الصعب تتبع مسار العملية وكيف وصلت إلى هنا.
  • السباق على الموارد (Race Conditions): يمكن أن تحاول خدمتان تحديث الحالة في نفس الوقت، مما يؤدي إلى بيانات غير متسقة.

باختصار، هذه الطريقة لا تتوسع ولا يمكن صيانتها على المدى الطويل.

البطل المنقذ: محركات تنسيق سير العمل (Workflow Engines)

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

ما هو معيار BPMN؟ جسر بين البيزنس والتقنية

أجمل ما في معظم محركات سير العمل الحديثة هو دعمها لمعيار BPMN (Business Process Model and Notation). هذا المعيار هو لغة مرئية (زي الـ Flowcharts) تسمح لك برسم خريطة سير العمل بطريقة يفهمها مدير المنتج، ومحلل الأعمال، والمطور على حد سواء. هذه الرسمة ليست مجرد صورة، بل هي الكود الفعلي الذي يفهمه المحرك وينفذه.

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

كيف أنقذتنا هذه المحركات من الجحيم؟

بمجرد أن تبنينا محرك سير عمل (في حالتنا كان Camunda، ولكن هناك خيارات ممتازة أخرى مثل Zeebe, Temporal, و Cadence)، تغير كل شيء. إليكم الفوائد العملية التي لمسناها:

1. مركزية الحالة والرؤية الكاملة

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

2. خدمات أبسط وأكثر استقلالية (Decoupling)

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

3. التعامل مع الأخطاء أصبح “شغل مرتب”

في مخطط BPMN نفسه، يمكنك تحديد سياسات إعادة المحاولة (e.g., Retry 3 times, with 5 minutes interval). يمكنك تحديد ماذا يحدث عند انتهاء المهلة (Timeout). والأهم، يمكنك تحديد “مهام التعويض” (Compensation Tasks). فمثلًا، لو فشلت خطوة “صرف المبلغ”، يمكن للمحرك تلقائيًا تشغيل مهمة “إلغاء الموافقة” ومهمة “إرجاع حالة العميل للسابق”. كل هذا يتم تعريفه بشكل مرئي وواضح.

مثال عملي: أتمتة طلبية متجر إلكتروني

لنفترض أن لدينا عملية طلب من متجر إلكتروني. باستخدام محرك سير عمل يدعم BPMN، ستبدو العملية هكذا:

  1. يبدأ الحدث باستلام طلب جديد.
  2. مهمة خدمة (Service Task): “معالجة الدفع”. يرتبط بهذه المهمة كود برمجي (Worker) يقوم باستدعاء بوابة الدفع.
  3. بوابة حصرية (Exclusive Gateway): هل نجح الدفع؟
    • إذا نعم: انتقل للخطوة التالية.
    • إذا لا: أرسل إشعارًا للعميل بالفشل وأنهِ العملية.
  4. مهمة خدمة: “حجز المنتجات من المخزون”.
  5. مهمة خدمة: “تجهيز الشحنة”.
  6. مهمة خدمة: “إرسال إشعار للعميل برقم التتبع”.
  7. ينتهي الحدث.

الآن، كيف يبدو الكود؟ لنأخذ مثال مهمة “معالجة الدفع” باستخدام Python ومحرك مثل Zeebe (وهو محرك سحابي حديث من Camunda).


# worker.py - هذا الكود يعمل بشكل مستقل ومنفصل
from pyzebe import ZeebeWorker, create_insecure_channel

# الاتصال بمحرك سير العمل
channel = create_insecure_channel(hostname="zeebe-broker.example.com", port=26500)
worker = ZeebeWorker(channel)

# هذا "العامل" يستمع للمهام من نوع "process-payment"
@worker.task(task_type="process-payment")
def process_payment_task(job):
    # job.variables يحتوي على كل البيانات القادمة من سير العمل (مثل رقم الطلب والمبلغ)
    order_id = job.variables.get("orderId")
    amount = job.variables.get("amount")

    print(f"Processing payment for order {order_id} with amount {amount}...")

    try:
        # هنا يتم استدعاء واجهة برمجة تطبيقات بوابة الدفع
        # payment_gateway.charge(amount, ...)

        # لنفترض أن الدفع نجح
        payment_successful = True
        transaction_id = "txn_12345abcde"
        print(f"Payment successful. Transaction ID: {transaction_id}")

        # إرجاع النتائج إلى محرك سير العمل ليستخدمها في الخطوات التالية
        return {
            "payment_successful": payment_successful,
            "transactionId": transaction_id
        }

    except Exception as e:
        print(f"Payment failed for order {order_id}: {e}")
        # يمكن إخبار المحرك بحدوث خطأ برمجي ليقوم بإعادة المحاولة أو معالجته
        # job.set_error_status("Payment Failed", str(e))
        return {"payment_successful": False}

# بدء تشغيل العامل للاستماع للمهام
print("Payment worker started. Waiting for jobs...")
worker.work()

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

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

بعد ما خضنا هذه التجربة، تعلمت كم شغلة بحب أشاركم فيها “من الآخر”:

  • ابدأ صغيرًا: لا تحاول أتمتة كل عمليات الشركة مرة واحدة. اختر أكثر عملية مؤلمة وتسبب “وجعة راس” للفريق والعملاء، وابدأ بها. النجاح في هذه العملية سيعطيك دفعة قوية لإكمال الباقي.
  • BPMN هو صديقك: استثمر الوقت في تعلم هذا المعيار. هو ليس مجرد أداة تقنية، بل أداة تواصل فعالة جدًا مع الأقسام الأخرى في الشركة.
  • اختر المحرك المناسب: هناك محركات تعمل كجزء من تطبيقك (Embedded) مثل Flowable، وهناك محركات مستقلة (Standalone) مثل Camunda Platform، وهناك محركات سحابية (Cloud-Native) مثل Zeebe و Temporal. كل نوع له إيجابياته وسلبياته، اختر بناءً على حجم فريقك وخبرته وبنية نظامك.
  • ليست حلًا سحريًا: محركات سير العمل ليست بديلاً عن التصميم الجيد للخدمات. هي أداة قوية لحل مشكلة محددة (التنسيق والحالة)، لكنها تضيف طبقة جديدة من التعقيد (عليك الآن إدارة وصيانة المحرك نفسه). استخدمها عندما تكون المشكلة حقيقية وتستدعي هذا الحل.

الخلاصة: من الفوضى إلى التنسيق المنظم ✅

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

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

أبو عمر

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

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

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

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

آخر المدونات

اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

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

4 يونيو، 2026 قراءة المزيد
ذكاء اصطناعي

كان نموذجنا اللغوي مؤلفاً بارعاً للكذب: كيف أنقذتنا تقنية RAG من جحيم الهلوسات؟

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

4 يونيو، 2026 قراءة المزيد
خوارزميات

التجزئة المتسقة (Consistent Hashing): كيف أنقذتنا من جحيم إعادة توزيع البيانات عند إضافة خادم جديد؟

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

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

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

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

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