Když několik vláken sdílí malý proxy pool, výběr náhodné položky může dvěma aktivním operacím přidělit stejný proxy. Fronta může uchovávat položky, které jsou právě dostupné k zapůjčení:

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)

Frontu sestavte jednou, před spuštěním pracovních vláken. proxy_urls obsahuje úplné URL adresy koncových bodů. Veřejní kandidáti jsou k dispozici v seznamu bezplatných proxy; použijte protokol a formát URL, který fetch_one podporuje. Stávající synchronní funkce fetch_one musí dokončit svou síťovou operaci a zavřít každou odpověď před návratem. Jinak by výpůjčka skončila, zatímco spojení stále používá daný proxy.

Queue.get atomicky odebere jednu dostupnou položku. Vyčerpaný pool čeká, místo aby opakovaně procházel sdílené příznaky. Pokud do pěti sekund žádná položka nepřijde, queue.Empty se dostane k volajícímu; pro tento výsledek zvolte politiku opakování, selhání nebo zrušení aplikace.

Blok finally vrací získanou položku po úspěchu i po výjimce. Neprohlašuje, že neúspěšný koncový bod je zdravý. Politiky karantény, nahrazení a ochlazení potřebují výslovnou cestu, místo aby tiše zahodily každý proxy, který narazí na dočasnou chybu.

Odstranění duplicitních identických URL řetězců brání duplicitním položkám ve frontě. Různé URL mohou stále odkazovat na stejný fyzický proxy nebo výstup; seskupte je záměrně, pokud má výlučnost platit pro tento sdílený zdroj. Fronta koordinuje vlákna v tomto procesu, nikoli pracovníky na jiných strojích.

Související články