כאשר כמה תהליכונים חולקים מאגר פרוקסי קטן, בחירה של רשומה אקראית עלולה לתת לשני פעולות פעילות את אותו פרוקסי. תור יכול להחזיק את הרשומות הזמינות כרגע להשאלה:

from contextlib import contextmanager
from queue import Queue

available = Queue()
for endpoint in dict.fromkeys(proxy_urls):
    available.put(endpoint)

@contextmanager
def borrow_proxy():
    endpoint = available.get(timeout=5)
    try:
        yield endpoint
    finally:
        available.put(endpoint)

def process_url(url):
    with borrow_proxy() as endpoint:
        return fetch_one(url, endpoint)

בנו את התור פעם אחת, לפני הפעלת תהליכוני העבודה. proxy_urls מכיל כתובות URL מלאות של נקודות קצה. מועמדים ציבוריים זמינים ברשימת הפרוקסי החינמית; השתמשו בפרוטוקול ובפורמט ה-URL ש-fetch_one תומך בהם. הפונקציה הסינכרונית fetch_one הקיימת חייבת לסיים את פעולת הרשת ולסגור כל תגובה לפני שהיא חוזרת. אחרת ההשאלה תסתיים בזמן שהחיבור עדיין משתמש באותו פרוקסי.

Queue.get מסיר באופן אטומי רשומה זמינה אחת. מאגר מותש ממתין במקום לסרוק שוב ושוב דגלים משותפים. אם לא מגיעה רשומה בתוך חמש שניות, queue.Empty מגיע לקורא; בחרו את מדיניות הניסיון החוזר, הכשל או הביטול של היישום עבור אותה תוצאה.

בלוק finally מחזיר רשומה שנרכשה לאחר הצלחה או חריגה. הוא אינו מצהיר שנקודת קצה שכשלה היא בריאה. מדיניות הסגר, ההחלפה והקירור זקוקה למסלול מפורש במקום להשליך בשקט כל פרוקסי שרואה שגיאה זמנית.

הסרת כפילויות של מחרוזות URL זהות מונעת רשומות תור כפולות. כתובות URL שונות עדיין יכולות להתייחס לאותו פרוקסי פיזי או ליציאה; קבצו אותן בכוונה אם בלעדיות צריכה לחול על המשאב המשותף הזה. התור מתאם תהליכונים בתהליך הזה, לא עובדים במכונות אחרות.

מאמרים קשורים