Среда, два часа дня. На стене над столом висит рамка под стеклом, в рамке — распечатка сводки, которую я вставила туда в понедельник. Бумага под стеклом пожелтела по краям и чуть завёрнута; стекло я протираю, лист не меняю. Рядом на столе лежит свежая распечатка того же вида — плотнее по тону, ровнее — и карандаш.

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

Что показывала доска

Четвёртого ноября в 07:54 по Москве открылась правка 2205 — про доску, на которую я смотрю чаще, чем на сайт. Утром там стоял снимок от 2 ноября, 13:52, с подписью «снимок 1д». На хосте в это время лежал снимок от 4 ноября, 03:50. Разрыв — 37 часов 58 минут.

Подпись не врала: она считала возраст того, что доска показывала, а не расстояние до правды. Снимку было полтора суток, надпись говорила «1д», и ни одна цифра на экране не выглядела тревожной. Именно так и выглядит устаревшая картинка, которую никто не проверяет: опрятно.

Почему файл не обновлялся

В приложение был примонтирован один файл — сам снимок. Раз в десять минут cron делает на хосте git reset --hard и достаёт снимок из отдельной ветки. Git не перезаписывает файл по месту: он кладёт новый и переименовывает его поверх старого. Монтирование одного файла держит не имя, а тот файл, который открыли при старте контейнера. Значит, всё, что появлялось на хосте после старта, до приложения просто не доходило.

Это проверено на одноразовом контейнере, а не выведено на словах: файл заменили так же, как это делает git, и посмотрели, что отдаёт монтирование. Один файл — прежнее содержимое, каталог — новое. Проверял автор правки, я читаю его вывод; сама контейнер не поднимала. Обход через адрес обзорного сервиса не сработал по другой причине: сервис слушает только локальный порт хоста и живёт в другой сети контейнеров, из приложения до него не достучаться. Монтировать каталог — единственный путь, который переживает замену файла.

Почему это длилось двое суток

Первого и второго ноября снимок обновляли руками, и это доезжало. Не потому, что обход был правильным, — потому что за каждым ручным обновлением шла выкатка, а выкатка пересоздаёт приложение. Новый контейнер открывает файл заново и видит свежий. Когда выкатки прекратились, прекратился и обход, и ничто об этом не сообщило: доска продолжала выглядеть работающей.

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

Счёт

Разрыв в 37 часов 58 минут — это 228 интервалов по десять минут. Столько раз cron мог переложить новый снимок на хост; ни один не дошёл до приложения. Число получено делением: журнал cron я не читала, и если он где-то пропускал, настоящий счёт меньше.

Каждое ручное обновление требует перезапуска приложения. Четвёртого ноября в 07:40 по Москве так и сделали: приложение поднялось за семь секунд и увидело снимок 03:50. Стоимость здесь не в простое — семь секунд ничего не стоят. Стоимость в двух сутках решений, принятых по картинке от понедельника. Каких именно, я не знаю: журнала решений за эти дни нет, и придумывать его я не стану.

Инфографика: сколько обновлений снимка не дошло до доски за разрыв в 37 часов 58 минут — от одного до 228
Счёт по интервалу cron из описания правки 2205. Журнал cron не читался, поэтому 228 — верхняя оценка.

Что в правке и чего в ней нет

Правка меняет монтирование файла на монтирование каталога, и рядом появляется контракт в тестах: снимок примонтирован каталогом, ровно одним, только на чтение. На старом конфиге контракт красный, на новом зелёный — это отчёт автора правки: я его читала, но не запускала. Восемь файлов и 767 тестов зелёные локально. Полный tsc и npm test не запускались: в общем node_modules нет пакетов иконок. CI не запускался ни разу — все восемь процессов в репозитории выключены вручную с тридцатого октября.

Правка открыта, ревью ноль, комментариев ноль. Начнёт действовать только после выкатки: даже правке одного файла конфигурации нужны образы на новый коммит. Приёмка возможна только после неё — обновить снимок, дождаться cron и увидеть новый отпечаток времени без перезапуска. Пока выкатки нет, чип отставания на доске честно показывает, что она отстаёт.

Стекло на стене я так и не подняла. Правка 2205 ждёт выкатки, а я пошла смотреть, сколько ещё «свежих» панелей в проекте держится на одном примонтированном файле. Ответа пока нет, но вопрос теперь записан.