Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумРазбор ошибок

Как воспроизвести плавающую ошибку

nullbyte
nullbyte
Ветеран
сообщений 2680
с апр
1 мая, 08:52первое сообщение

Раз в три-четыре часа прогон валится на разборе страницы. Беру тот же список, тот же порядок, запускаю заново: проходит целиком. Беру только упавший кусок, сорок адресов: проходит и он.

Смотрел, нет ли привязки ко времени суток. Нету.

когда падало за сутки
когда падало за сутки

Отключил многопоточность и прогнал шесть часов в один поток. Ни одного падения. Дальше идеи кончились. Хочу нормальный порядок действий вместо ещё одной ночи наблюдений.

если не воспроизводится, значит не понял
Пётр Мельник
Пётр Мельник
Участник
сообщений 810
с июл
8 октября, 11:09#2

Шесть часов в один поток без падения это уже половина ответа. Ищите общее состояние между потоками.

сначала замер, потом мнение
nullbyte
nullbyte
Ветеран
сообщений 2680
с апр
15 марта, 14:26#3
Пётр Мельник: ищите общее состояние между потоками

Общего у меня немного: счётчик обработанных и один сеанс requests на всех. Задачи каждый берёт из очереди, никто ни к кому не лезет.

если не воспроизводится, значит не понял
tcpdump_fan
tcpdump_fan
Знаток
сообщений 1010
с июн
22 августа, 17:43#4

Одного сеанса на всех уже достаточно. Внутри него пул соединений, и при разрыве соседнее соединение уходит другому потоку вместе с недочитанным телом. Отсюда и разбор, который спотыкается на середине.

Дальше про сам порядок ловли, он одинаковый для любой плавающей ошибки.

Первое: усилить условия, при которых она вылезает. Раз падает раз в четыре часа при тридцати потоках, ставьте девяносто и убирайте паузы. Такая ошибка живёт на редком совпадении, а частота совпадений растёт быстрее числа потоков.

Второе: каждая строка журнала несёт имя потока и номер задачи. Иначе потом ничего не сведёте.

log = logging.getLogger("progon")

def obrabotat(zadacha): metka = "%s/%s" % (threading.current_thread().name, zadacha["id"]) log.info("vzyal %s", metka) otvet = ses.get(zadacha["url"], timeout=20) log.info("otvet %s %s bayt", metka, len(otvet.content)) return razobrat(otvet) ```

Третье: падение оставляет после себя вещдок. Одной строчки в журнале мало.

слушаю провод, а не догадки
Дарья Смолина
Дарья Смолина
Участник
сообщений 340
с дек
1 января, 08:00#5

Про вещдок подхвачу. У нас под это отдельная папка, туда складывается всё про упавшую задачу.

except Exception as e:
    imya = "sled/%d-%s.txt" % (int(time.time()), zadacha["id"])
    with open(imya, "w", encoding="utf-8") as f:
        f.write("%s\n%s\n" % (zadacha["url"], e))
        f.write(repr(dict(otvet.headers)) + "\n\n")
        f.write(otvet.text)
    raise

Через сутки у вас четыре таких файла, и по ним сразу видно, ломается одно и то же или каждый раз разное.

nullbyte
nullbyte
Ветеран
сообщений 2680
с апр
8 июня, 11:17#6

Поймал четыре штуки. У всех тело обрезано на середине, длина не сходится с заголовком Content-Length. Значит разбор тут ни при чём.

если не воспроизводится, значит не понял
Влад Терентьев
Влад Терентьев
Участник
сообщений 745
с авг
15 ноября, 14:34#7

Обрезанное тело при общем сеансе укладывается ровно в то, о чём выше сказал tcpdump_fan.

Сделайте свой сеанс на каждый поток, через локальные данные потока.

mestnoe = threading.local()

def sessiya(): if not hasattr(mestnoe, "ses"): mestnoe.ses = requests.Session() return mestnoe.ses ```

И проверьте, что объект ответа нигде не уезжает в другой поток. Такое бывает, когда ответ кладут в общий кэш целиком.

cronjob
cronjob
Новичок
сообщений 205
с фев, второй сезон
22 апреля, 17:51#8

а если просто ловить исключение и повторять задачу? проще же

nullbyte
nullbyte
Ветеран
сообщений 2680
с апр
1 сентября, 08:08#9

Повтор спрячет источник. У меня так уже было в прошлом прогоне: строки в выгрузке тихо задваивались, потому что повторная задача дописывала свою копию.

Что помогло по шагам. Подняли потоки до девяноста и убрали паузы, ошибка стала приходить каждые семь минут вместо четырёх часов. Дальше свой сеанс на поток. За ночь ни одного падения, папка со следами пустая. Оставлю её включённой, пусть лежит.

если не воспроизводится, значит не понял