När flera trådar delar en liten proxy-pool kan valet av en slumpmässig post ge två aktiva operationer samma proxy. En kö kan hålla posterna som just nu är lediga att låna:

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)

Bygg kön en gång, innan arbetstrådarna startas. proxy_urls innehåller fullständiga endpoint-URL:er. Offentliga kandidater finns i listan över gratis proxyservrar; använd det protokoll och URL-format som fetch_one stöder. Den befintliga synkrona fetch_one-funktionen måste slutföra nätverksoperationen och stänga alla svar innan den återvänder. Annars skulle lånet ta slut medan anslutningen fortfarande använder proxyn.

Queue.get tar bort en tillgänglig post atomärt. En uttömd pool väntar i stället för att upprepade gånger skanna delade flaggor. Om ingen post kommer in inom fem sekunder når queue.Empty anroparen; välj programmets policy för nytt försök, fel eller avbrott för det resultatet.

Finally-blocket lämnar tillbaka en post som hämtats efter framgång eller ett undantag. Det deklarerar inte att en misslyckad endpoint är frisk. Karantän-, ersättnings- och nedkylningspolicyer behöver en uttrycklig väg i stället för att tyst kasta bort varje proxy som ser ett tillfälligt fel.

Deduplicering av identiska URL-strängar förhindrar dubbla köposter. Olika URL:er kan fortfarande peka på samma fysiska proxy eller utgång; gruppera dem medvetet om exklusivitet ska gälla för den delade resursen. Kön samordnar trådar i den här processen, inte arbetare på andra maskiner.

Relaterade artiklar