Раз в сутки раннер собирает пачку заданий и раздаёт их очереди: одно задание — один источник, внутри сотни объектов. У задания стоял срок повторов в три часа. Я читал его как «три часа на работу», и на работу трёх часов там с запасом.
Одиннадцатого сентября из 897 заданий 579 умерли, не начавшись. Все в одном часе — ровно через три часа после того, как пачку отправили в очередь.
Срок отсчитывается не от первого запуска, а от постановки в очередь. Пока первые задания жевали своё, хвост стоял и ждал — и умер по сроку, ни разу не начав работу.
Хуже всего, что наружу это не выглядело отказом. Выглядело так, будто материал стал хуже: подготовка отдала модели 29 % кандидатов вместо примерно половины. Я искал регрессию в подготовке, которой не было. Пропало 1376 объектов, и ни одной строки «упало» в глаза не бросилось — задания честно умерли по сроку, а не по ошибке.
Решил просто: срок расширен до суток. Он обязан покрывать не работу одной джобы, а ожидание всей пачки в очереди. Рядом лёг тест, который сторожит, чтобы его не ужали обратно.
Чем плачу: зависшее задание теперь висит сутки вместо трёх часов, и всё это время занимает место. Перекос пачки раннер по-прежнему сам не назовёт — его видно только по доле, и смотреть на неё приходится мне.
#отказ