Когато няколко нишки споделят малък прокси пул, изборът на случаен запис може да даде на две активни операции един и същ прокси. Опашка може да съхранява записите, които в момента са свободни за заемане:

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 адреси все още могат да сочат към едно и също физическо прокси или изход; групирайте ги умишлено, ако изключителността трябва да важи за този споделен ресурс. Опашката координира нишките в този процес, а не работниците на други машини.

Подобни статии