إعادة محاولة الدوال غير المتزامنة

يوضّح هذا المستند كيفية طلب وظائف ملفّ الشخصي في الخلفية (غير المستندة إلى بروتوكول HTTPS) لإعادة المحاولة في حال حدوث خطأ.

الدلالات المتعلّقة بإعادة المحاولة

توفّر Cloud Functions تنفيذًا لمرة واحدة على الأقل لدالة مستندة إلى الأحداث لكل حدث ينبعث من مصدر حدث. بشكلٍ تلقائي، إذا انتهى تنفيذ دالة بخطأ، لا يتمّ تنفيذ الدالة مرة أخرى ويتمّ إسقاط الحدث. عند تفعيل عمليات إعادة المحاولة في دالة مستندة إلى حدث، يعيد Cloud Functions محاولة استدعاء الدالة التي تعذّر تنفيذها إلى أن يتم إكمالها بنجاح أو تنتهي مهلة إعادة المحاولة.

بالنسبة إلى الدوالّ من الجيل الثاني، تنتهي صلاحية مهلة إعادة المحاولة بعد 24 ساعة. بالنسبة إلى الدوالّ من الجيل الأول، تنتهي صلاحيتها بعد 7 أيام. يعيد Cloud Functions تنفيذ الدوال المستندة إلى الأحداث التي تم إنشاؤها حديثًا باستخدام استراتيجية التراجع التدرّجي، مع فترة انتظار متزايدة تتراوح بين 10 و600 ثانية. تُطبَّق هذه السياسة على الدوال الجديدة عند نشرها لأول مرة. ولا يتم تطبيقها بأثر رجعي على الدوالّ الحالية التي تم نشرها لأول مرة قبل سريان التغييرات الموضّحة في ملاحظات الإصدار هذه، حتى في حال إعادة نشر الدوالّ.

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

أسباب تعذُّر إكمال الدوال المستندة إلى الأحداث

في حالات نادرة، قد تنتهي وظيفة قبل الأوان بسبب خطأ داخلي، وقد تتم إعادة محاولة تنفيذ الوظيفة تلقائيًا أو لا تتم تلقائيًا.

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

  • تحتوي الدالة على خطأ ويُلقي وقت التشغيل استثناءً.
  • لا يمكن للدالة الوصول إلى نقطة نهاية الخدمة، أو تنتهي مهلة الانتظار أثناء محاولة إجراء ذلك.
  • تُلقي الدالة استثناءً عن قصد (على سبيل المثال، عندما تؤدي إحدى المَعلمات إلى عدم اجتياز عملية التحقّق).
  • تعرض دالة Node.js وعدًا مرفوضًا، أو تمرِّر قيمة غير null إلى دالة ردّ اتصال.

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

تفعيل عمليات إعادة المحاولة أو إيقافها

ضبط عمليات إعادة المحاولة من وحدة التحكّم

في حال إنشاء دالة جديدة:

  1. من شاشة إنشاء دالة، ضمن المشغِّل، اختَر نوع الحدث الذي سيعمل كمشغِّل للدالة.
  2. ضَع علامة في مربّع الاختيار إعادة المحاولة عند حدوث خطأ لتفعيل عمليات إعادة المحاولة.

إذا كنت بصدد تعديل دالة حالية:

  1. من صفحة Cloud Functions نظرة عامة، انقر على اسم الدالة التي تعدّلها لفتح شاشة تفاصيل الدالة، ثم اختَر تعديل من شريط القوائم لعرض لوحة العامل المشغِّل.
  2. ضَع علامة في مربّع الاختيار إعادة المحاولة عند حدوث خطأ أو أزِلها لتفعيل إعادة المحاولة أو إيقافها.

ضبط عمليات إعادة المحاولة من رمز الدالة

باستخدام Cloud Functions for Firebase، يمكنك تفعيل عمليات إعادة المحاولة في الرمز البرمجي لإحدى الدوالّ. لإجراء ذلك لدالة تعمل في الخلفية مثل functions.foo.onBar(myHandler);، استخدِم runWith واضبط سياسة تعذُّر التنفيذ:

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

يؤدي ضبط true كما هو موضّح إلى ضبط دالة لإعادة المحاولة في حال تعذّر إكمالها.

أفضل الممارسات

يصف هذا القسم أفضل الممارسات لاستخدام عمليات إعادة المحاولة.

استخدام إعادة المحاولة للتعامل مع الأخطاء العابرة

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

اضبط شرطًا نهائيًا لتجنُّب تكرار عمليات إعادة المحاولة بلا حدود.

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

من الطرق البسيطة والفعّالة تجاهل الأحداث التي لها طوابع زمنية أقدم من وقت معيّن. يساعد ذلك في تجنُّب عمليات التنفيذ المفرطة عندما تكون الأعطال إما مستمرة أو تستمر لفترة أطول من المتوقّع.

على سبيل المثال، يتخلّص مقتطف الرمز البرمجي هذا من جميع الأحداث التي مرّ عليها أكثر من 10 ثوانٍ:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

استخدام catch مع Promises

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

في ما يلي مثال على الإجراءات التي يجب اتّخاذها:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

جعل الدوال المستندة إلى الأحداث والتي يمكن إعادة تجربتها أحادية المفعول

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

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

ضبط سياسة إعادة المحاولة

استنادًا إلى احتياجات الدالة، قد تحتاج إلى ضبط استراتيجية إعادة المحاولة مباشرةً. سيتيح لك ذلك إعداد أيّ مجموعة من الإعدادات التالية:

  • يمكنك تقصير فترة إعادة المحاولة من 7 أيام إلى 10 دقائق كحد أدنى.
  • يمكنك تغيير الحد الأدنى والحد الأقصى لوقت الانتظار في استراتيجية الانتظار المتزايد إعادة المحاولة.
  • يمكنك تغيير استراتيجية إعادة المحاولة لإعادة المحاولة على الفور.
  • اضبط موضوع رسائل غير قابلة للتسليم.
  • حدِّد الحد الأقصى والحد الأدنى لعدد محاولات الإرسال.

لضبط سياسة إعادة المحاولة:

  1. اكتب دالة HTTP.
  2. استخدِم واجهة برمجة التطبيقات Pub/Sub لإنشاء اشتراك Pub/Sub، مع تحديد عنوان URL للدالة كهدف.

اطّلِع على مستندات Pub/Sub حول التعامل مع حالات الفشل لمزيد من المعلومات حول ضبط Pub/Sub مباشرةً.