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

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

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

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

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

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

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

دلالات إعادة المحاولة

توفّر Cloud Functions تنفيذًا لمرة واحدة على الأقل لدالة مستندة إلى الأحداث لكل حدث صادر عن مصدر حدث. تعتمد طريقة ضبط عمليات إعادة المحاولة على طريقة إنشاء الدالة:

  • تتطلّب الدوال التي تم إنشاؤها في Google Cloud Console أو باستخدام Cloud Run Admin API أن تنشئ وتدير مشغّلات الأحداث بشكل منفصل. تتضمّن المشغّلات سلوكيات إعادة محاولة تلقائية يمكنك تخصيصها لتناسب احتياجات الدالة.
  • ستنشئ الدوال التي تم إنشاؤها باستخدام Cloud Functions v2 API بشكل ضمني مشغّلات الأحداث اللازمة، مثل مواضيع Pub/Sub أو مشغّلات Eventarc. يتم تلقائيًا إيقاف عمليات إعادة المحاولة لهذه المشغّلات، ويمكن إعادة تفعيلها باستخدام Cloud Functions v2 API.

الدوال المستندة إلى الأحداث التي تم إنشاؤها باستخدام Cloud Run

تتطلّب الدوال التي يتم إنشاؤها في Google Cloud Console أو باستخدام واجهة برمجة التطبيقات Cloud Run Admin إنشاء مشغّلات الأحداث وإدارتها بشكل منفصل. ننصحك بشدة بمراجعة السلوك التلقائي لكل نوع من أنواع المشغّلات:

الدوال المستندة إلى الأحداث التي تم إنشاؤها باستخدام الإصدار 2 من Cloud Functions API

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

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

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

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

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

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

يؤدي ضبط true كما هو موضّح إلى إعداد دالة لإعادة المحاولة عند حدوث خطأ.

فترة إعادة المحاولة

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

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

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

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

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

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

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

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

على سبيل المثال، يتجاهل مقتطف الرمز هذا جميع الأحداث التي مرّ عليها أكثر من 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);
});

جعل الدوال المستندة إلى الأحداث والقابلة لإعادة المحاولة متطابقة

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

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

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

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

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

لضبط سياسة إعادة المحاولة، اتّبِع الخطوات التالية:

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

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