Utworzenie puli procesów roboczych nie przekazuje wywołującemu pobranych stron. Zachowaj i zużywaj wartości zwracane przez przesłaną pracę:

from concurrent.futures import ThreadPoolExecutor
import urllib3

manager = urllib3.ProxyManager(
    'http://proxy.example:8080',
    maxsize=4,
    block=True,
)

def fetch(url):
    response = manager.request(
        'GET', url, timeout=urllib3.Timeout(connect=5, read=15),
    )
    return url, response.status, response.data

try:
    with ThreadPoolExecutor(max_workers=4) as workers:
        results = list(workers.map(fetch, urls))
finally:
    manager.clear()

Ten fragment zakłada ograniczoną listę adresów URL i typowe rozmiary odpowiedzi. W przypadku dozwolonych kontroli publicznych adresów URL bez uwierzytelniania proxy kandydat z listy proxy HTTP może zastąpić przykładowy punkt końcowy HTTP menedżera. Każdy wynik zawiera swój adres URL, aby wywołujący mógł powiązać stan i treść z właściwym żądaniem. map zwraca wyniki w kolejności wejściowej; wyjątek w wątku roboczym jest zgłaszany, gdy ten wynik jest pobierany.

Skonfigurowany ProxyManager posiada pulę połączeń dla żądań. W używanym tutaj domyślnym trybie wstępnie wczytanej odpowiedzi urllib3 odczytuje treść i zwraca połączenie do swojej puli. Wersja strumieniowa wymagałaby jawnego zużycia i zwolnienia połączenia.

maxsize zwykle kontroluje utrzymywane połączenia wielokrotnego użytku, a nie twardy limit każdego otwartego gniazda. block=True zmienia odpowiednie zachowanie puli, aby wywołujący czekali na wolne połączenie zamiast otwierać dodatkowe ponad limit tej puli.

Liczba wątków roboczych ogranicza współbieżne wywołania w tym przykładzie. Przy wielu miejscach docelowych znaczenie mają także układ puli i trasa używana dla tuneli HTTPS; ustawienia jednej puli nie należy opisywać jako jednego globalnego limitu gniazd dla każdego hosta.

Powiązane artykuły