Een proxypool delen tussen Python-threads met een wachtrij
Gebruik een gesynchroniseerde wachtrij en een finally-blok om één proxy te reserveren voor een synchrone threadbewerking en die daarna terug te geven.
Wanneer meerdere threads een kleine proxypool delen, kan het kiezen van een willekeurige vermelding twee actieve bewerkingen dezelfde proxy geven. Een wachtrij kan de vermeldingen bevatten die op dit moment te leen zijn:
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)
Bouw de wachtrij één keer, voordat de werkthreads starten. proxy_urls bevat volledige eindpunt-URL's. Openbare kandidaten staan in de lijst met gratis proxies; gebruik het protocol en URL-formaat dat fetch_one ondersteunt. De bestaande synchrone fetch_one-functie moet zijn netwerkbewerking afronden en elk antwoord sluiten voordat hij terugkeert. Anders zou de lening eindigen terwijl de verbinding die proxy nog gebruikt.
Queue.get verwijdert atomair één beschikbare vermelding. Een uitgeputte pool wacht in plaats van herhaaldelijk gedeelde vlaggen te scannen. Als er binnen vijf seconden geen vermelding komt, bereikt queue.Empty de aanroeper; kies het beleid voor opnieuw proberen, mislukken of annuleren van de toepassing voor dat resultaat.
Het finally-blok geeft een verkregen vermelding terug na succes of een uitzondering. Het verklaart niet dat een mislukt eindpunt gezond is. Quarantaine-, vervangings- en afkoelbeleid hebben een expliciet pad nodig in plaats van elke proxy die een tijdelijke fout ziet stilzwijgend weg te gooien.
Het verwijderen van dubbele identieke URL-strings voorkomt dubbele wachtrijvermeldingen. Verschillende URL's kunnen nog steeds naar dezelfde fysieke proxy of uitgang verwijzen; groepeer ze bewust als exclusiviteit moet gelden voor die gedeelde bron. De wachtrij coördineert threads in dit proces, niet workers op andere machines.