asyncio.gather با return_exceptions=True استثناهای وظیفه‌ها را در فهرست نتایجش قرار می‌دهد. پس انتظار برای دسته بدون دیدن استثنا به معنای موفقیت همه درخواست‌های پروکسی نیست.

مقصد و پروکسی انتخاب‌شده را کنار awaitableهای ارسال‌شده نگه دارید و سپس هر نتیجه را بررسی کنید:

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 را اعمال کنید.

وقتی نتایج دیده شوند، برنامه می‌تواند خرابی‌های اتصال را از پاسخ‌های مقصد جدا کند و تصمیم بگیرد کدام کار ارزش تلاش دیگر را دارد.

مقالات مرتبط