Спільне використання пулу проксі між потоками Python за допомогою черги
Використовуйте синхронізовану чергу та блок finally, щоб зарезервувати один проксі для синхронної потокової операції, а потім повернути його.
Коли кілька потоків ділять невеликий пул проксі, вибір випадкового запису може дати двом активним операціям той самий проксі. Черга може зберігати записи, доступні для позичання зараз:
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 усе ще можуть указувати на той самий фізичний проксі або вихід; групуйте їх навмисно, якщо ексклюзивність має застосовуватися до цього спільного ресурсу. Черга координує потоки в цьому процесі, а не працівників на інших машинах.