Проверки прокси на Python: почему Future.cancel() оставляет потоки работающими
Поймите, почему отмена ожидающих futures не останавливает активные сетевые проверки, и ограничьте гонку прокси, не утверждая, что она доказывает работоспособность назначения.
Один worker находит рабочий прокси. Вы возвращаете его адрес, вызываете cancel для остальных futures и ожидаете, что сетевая активность прекратится. Может и не прекратиться.
Future можно отменить до запуска его callable. Если поток уже выполняет запрос, отмена его Future не прерывает эту операцию с сокетом. Worker нужна собственная ограниченная сетевая операция и путь очистки.
Время жизни executor тоже важно. Выход из контекста ThreadPoolExecutor ждёт завершения его работы. Найти один быстрый результат, а затем ждать несколько медленных worker — из-за этого общая задержка вызывающего может совсем не походить на заявленную задержку победителя.
Ограничьте гонку до её начала
- Ограничьте число одновременных проверок вместо отправки неограниченного публичного списка. Бесплатный список прокси даёт кандидатов для входа проверяющего, причём протокол каждой конечной точки сохраняется для worker.
- Дайте каждому запросу подходящую политику соединения и чтения.
- Дайте вызывающему общий бюджет решения.
- Определите, кто опустошает или закрывает результаты worker, переживших решение.
Меньше ждать Future — не то же самое, что сократить его базовый запрос. Точно так же отказ от результата не освобождает сразу все сетевые ресурсы.
Первый успешный результат — это ещё и только первая успешная проверка. Он может зависеть от планирования, кэшированных соединений и конкретного назначения проверки. Он не доказывает, что конечная точка универсально самая быстрая или что реальная задача завершится успешно.
Часто небольшой сохраняемый пул со свежими наблюдениями проще, чем гонка со всем списком перед каждой загрузкой. Используйте результат реальной операции для обновления записи вместе с контролируемой политикой восстановления при сбоях. Предварительная проверка должна окупать свою стоимость, а не удваивать каждую задачу по привычке.