Кога неколку нишки делат мал прокси базен, изборот на случаен запис може да им даде ист прокси на две активни операции. Редот може да ги чува записите што се моментално достапни за позајмување:

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 адреси сè уште може да се однесуваат на истиот физички прокси или излез; групирајте ги намерно ако ексклузивноста треба да важи за тој споделен ресурс. Редот ги координира нишките во овој процес, не работниците на други машини.

Поврзани статии