التعامل مع طلبات البروكسي الفاشلة باستخدام asyncio.gather
افحص الاستثناءات التي يعيدها asyncio.gather وأبقِ كل نتيجة مرتبطة بالبروكسي المختار لها.
يضع asyncio.gather مع return_exceptions=True استثناءات المهام في قائمة نتائجه. لذا فإن انتظار الدفعة دون ظهور استثناء لا يعني أن كل طلب بروكسي قد نجح.
أبقِ الوجهة والبروكسي المختار إلى جانب الكائنات المنتظرة المُرسلة، ثم افحص كل نتيجة:
outcomes = await asyncio.gather(*jobs, return_exceptions=True)
for (url, proxy), outcome in zip(routes, outcomes):
if isinstance(outcome, BaseException):
record_failure(url, proxy, outcome)
else:
record_success(url, proxy, outcome)
تحتوي jobs على كوروتينات الطلبات الخاصة بالتطبيق؛ وتحتوي routes على أزواج (url, proxy) المقابلة لها بالترتيب نفسه. دوال التسجيل هي معالجة النتائج الخاصة بالتطبيق. يحافظ gather على ترتيب الإدخال حتى عندما يختلف ترتيب الإكمال.
صنّف CancelledError العائدة من مهمة فرعية على أنها إلغاء بدلًا من إلقاء اللوم على البروكسي الخاص بها. لا يزال إلغاء gather الخارجي ينتقل إلى المهام الفرعية غير المكتملة؛ ولا يحوّل return_exceptions ذلك الإلغاء إلى نجاح عادي.
تقع معالجة حالة HTTP أيضًا داخل عملية الطلب. لا يرفع aiohttp استثناءً لكل خطأ HTTP افتراضيًا، لذا أعِد الحالة أو طبّق raise_for_status وفقًا لسياسة المهمة.
بمجرد أن تصبح النتائج مرئية، يمكن للتطبيق التمييز بين أعطال الاتصال واستجابات الوجهة وتحديد أي عمل يستحق محاولة أخرى.