Zdieľanie proxy poolu medzi vláknami Pythonu pomocou frontu
Použite synchronizovaný front a blok finally na rezervovanie jedného proxy pre synchrónnu vláknovú operáciu a jeho následné vrátenie.
Keď niekoľko vlákien zdieľa malý proxy pool, výber náhodnej položky môže dvom aktívnym operáciám prideliť rovnaký proxy. Front môže uchovávať položky, ktoré sú práve dostupné na zapožičanie:
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)
Zostavte front raz, pred spustením pracovných vlákien. proxy_urls obsahuje úplné URL adresy koncových bodov. Verejní kandidáti sú dostupní v zozname bezplatných proxy; použite protokol a formát URL, ktoré podporuje fetch_one. Existujúca synchrónna funkcia fetch_one musí pred návratom dokončiť svoju sieťovú operáciu a zavrieť každú odpoveď. Inak by sa výpožička skončila, kým spojenie ešte používa daný proxy.
Queue.get atomicky odoberie jednu dostupnú položku. Vyčerpaný pool čaká, namiesto opakovaného prehľadávania zdieľaných príznakov. Ak do piatich sekúnd nepríde žiadna položka, queue.Empty sa dostane k volajúcemu; pre tento výsledok zvoľte politiku opakovania, zlyhania alebo zrušenia aplikácie.
Blok finally vracia získanú položku po úspechu aj po výnimke. Nevyhlasuje, že neúspešný koncový bod je zdravý. Politiky karantény, nahradenia a ochladenia potrebujú výslovnú cestu, namiesto tichého zahodenia každého proxy, ktorý narazí na dočasnú chybu.
Odstraňovanie duplikátov identických URL reťazcov bráni dvojitým položkám vo fronte. Rôzne URL môžu stále odkazovať na rovnaký fyzický proxy alebo výstup; zoskupte ich zámerne, ak má výlučnosť platiť pre tento zdieľaný zdroj. Front koordinuje vlákna v tomto procese, nie pracovníkov na iných strojoch.