تمرر دالة map في التجمع عنصرًا واحدًا إلى العامل في كل مرة. اجعل ذلك العنصر مهمة كاملة، تتضمن عنوان URL والوكيل المختار، حتى لا يستنتج العامل مساره من قائمة عامة متغيرة.

بالنسبة إلى urls المحدودة، قدّم قائمة غير فارغة من عناوين URL للوكيل تم التحقق منها. تتوفر مرشحات HTTP العامة في قائمة وكلاء HTTP:

from concurrent.futures import ThreadPoolExecutor
from itertools import cycle
import requests

def fetch(job):
    url, proxy_url = job
    proxies = {"http": proxy_url, "https": proxy_url}
    with requests.get(url, proxies=proxies, timeout=(5, 15)) as response:
        response.raise_for_status()
        return url, response.text

if not proxy_urls:
    raise ValueError("No proxy endpoints were supplied")

jobs = zip(urls, cycle(proxy_urls))
with ThreadPoolExecutor(max_workers=5) as executor:
    for url, body in executor.map(fetch, jobs):
        handle_result(url, body)

يوفّر التطبيق urls وproxy_urls وhandle_result. يوزّع المنسّق نقاط النهاية بترتيب متكرر؛ ويتلقى كل عامل زوجًا ثابتًا واحدًا. كما أن تكرار النتائج يُظهر استثناءات العمال.

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

ينبغي أن تنشئ إعادة المحاولة محاولة جديدة محدودة لعنوان URL نفسه. تجنّب نداءات إعادة المحاولة المتكررة التي تزيل إدخالات من قائمة مشتركة: قد يكون عامل آخر يختار منها، والقائمة المستنفدة لا تزال تحتاج إلى نتيجة صريحة.

مقالات ذات صلة