возникла необходимость поставить таймаут на чтение данных через HTTPConnection, посоветуйте как
Проблема в чем - не уверен, что это хороший метод, может есть какое-то другое решение?
Написал для себя скрипт скачки большого кол-ва страничек, бывает что какой-то из потоков подвисает намертво из-за потери связи с сервером, и никакие таймауты сокетов не работают…
После поиска в инете, заранее несколько замечаний:
1. Писать свой собственный модуль на основе сокетов я не осилю
2. Требуется прервать именно работающий read() - связь установлена, данные идут, питон не получает ни ошибки, ни конца потока, и тут мы хотим все это дело прервать сиюмоментно, не дожидаясь ни единого байта (т.е. даже read(блоками) не подходит)
3. Использую HTTPConnection для Keep-Alive (в примере заголовки убраны для меньшего объема)
Для тестов на веб-сервере сделал искуственно замедленный скрипт (страничка выдается 20 сек) -
<?php
for ($a=1;$a<=20;$a++) {
echo($a."<br>");
sleep(1);
flush();
}
?>
Питоновский скрипт пытается её скачать, если за 2 сек (взято от балды для быстроты тестов) страничка не скачивается - пытается повторить сначала, по истечению 5 попыток отваливается.
server = "localhost" url = "http://localhost/delay/gen20.php" def timeout(sock): logger.info("Timeout, trying to reconnect") sock.close() def do_read(): conn = http.client.HTTPConnection(server,timeout=5) logger.debug("HTTP conn created") for errcount in range(5): conn.connect() logger.debug(url + " - start fetch. Try %d of 5" % (errcount+1)) try: conn.request("GET",url) resp = conn.getresponse() t = Timer(2,timeout,[conn.sock]) t.start() data = resp.read() print(data) t.cancel() break except socket.timeout: resp.close() del resp conn.close() continue