Când mai multe fire partajează un pool mic de proxy, alegerea unei intrări aleatorii poate da același proxy la două operații active. O coadă poate păstra intrările disponibile momentan pentru împrumut:

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)

Construiți coada o singură dată, înainte de a porni firele de lucru. proxy_urls conține URL-uri complete de endpoint. Candidații publici sunt disponibili în lista de proxy gratuite; folosiți protocolul și formatul URL acceptate de fetch_one. Funcția fetch_one sincronă existentă trebuie să își termine operația de rețea și să închidă orice răspuns înainte de a reveni. Altfel, împrumutul s-ar termina în timp ce conexiunea încă folosește acel proxy.

Queue.get elimină atomic o intrare disponibilă. Un pool epuizat așteaptă în loc să scaneze repetat steaguri partajate. Dacă nu sosește nicio intrare în cinci secunde, queue.Empty ajunge la apelant; alegeți politica de reîncercare, eșec sau anulare a aplicației pentru acel rezultat.

Blocul finally returnează o intrare dobândită după succes sau excepție. Nu declară că un endpoint eșuat este sănătos. Politicile de carantină, înlocuire și răcire au nevoie de o cale explicită în loc să arunce în tăcere fiecare proxy care vede o eroare temporară.

Eliminarea duplicatelor pentru șiruri URL identice previne intrările duble în coadă. URL-uri distincte pot indica în continuare același proxy fizic sau ieșire; grupați-le deliberat dacă exclusivitatea trebuie să se aplice acelei resurse partajate. Coada coordonează firele din acest proces, nu lucrătorii de pe alte mașini.

Articole similare