مُحمّل النسخ الاحتياطية المقسّم يتجاوز حد معدل طلبات Discourse

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

يستخدم مرفّع النسخ الاحتياطية مقاطع ثابتة بحجم 5 ميغابايت، وعلى اتصال سريع بما يكفي، يمكنه توليد عدد كافٍ من الطلبات لتجاوز حد معدل الطلبات على مستوى التطبيق الخاص بـ Discourse نفسه. عندما يحدث ذلك، يعيد الخادم استجابة HTTP 429، لكن المرفّع المقسّم لا يعيد محاولة الاستجابات 429 ولا يلتزم بترويسة Retry-After. ونتيجة لذلك، يفشل رفع النسخة الاحتياطية بأكملها.

تُحوَّل الاستجابات غير 2xx إلى خطأ:

if (ev.target.status < 200 || ev.target.status >= 300) {
  const error = new Error("Non 2xx");
  error.source = ev.target;
  reject(error);
  return;
}

منطق إعادة المحاولة هو:

_shouldRetry(err) {
  if (err.source && typeof err.source.status === "number") {
    const { status } = err.source;

    return (
      status === 0 ||
      status === 409 ||
      status === 423 ||
      (status >= 500 && status < 600)
    );
  }

  return false;
}

لذلك، لا يُعتبر HTTP 429 قابلًا لإعادة المحاولة صراحةً.

استجابة 429 واحدة تكفي لإخفاق وعد (promise) رفع المقطع، مما يؤدي في النهاية إلى تشغيل upload-error لرفع النسخة الاحتياطية بأكملها.

كما لا يوجد أي معالجة لترويسة الاستجابة Retry-After.


وجدت هذا الموضوع من عام 2021 الذي انحرف بسرعة، لكنه يبدو أنه نفس الشيء تمامًا