Программирование с ИИ
ENRU
12.3

Публикация и обновления

почему старая версия живёт дольше, чем кажется

Что это

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

Поэтому главный вопрос при каждом обновлении не «как выложить», а «что будет с теми, кто ещё на старой». Этот вопрос не задаёт ни ИИ, ни инструменты публикации — его задаёшь только ты.

Как выглядит в коде

Три способа публикации — три разных скорости

Что публикуемКак попадает к людямМожно откатить
сайтмгновенно, при следующем открытиида, мгновенно
сервер, APIмгновенно, всем сразуда, если готовился
приложение в магазинепосле проверки, по желанию людейнет

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

Сайт: кэш, и как сборка его обходит

Собираем проект два раза подряд, не меняя ни строчки:

$ npx vite build
dist/assets/index-Dg-DehUb.js  222.57 kB │ gzip: 69.34 kB
$ npx vite build
dist/assets/index-Dg-DehUb.js  222.57 kB │ gzip: 69.34 kB

Имя файла одно и то же. Теперь меняем в тексте одно слово и собираем снова:

$ npx vite build
dist/assets/index-BKJJYt4K.js  222.59 kB │ gzip: 69.36 kB

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

Но один файл в этой схеме имени не меняет:

измерено
dist/index.html                  0.39 kB
dist/assets/index-BKJJYt4K.js  222.59 kB

index.html — тот самый файл, в котором написано, какой из хэшированных файлов загружать. Его кэшировать нельзя. Если хостинг закэширует index.html на сутки, пользователь сутки будет открывать старую страницу, ссылающуюся на старый код, и никакая публикация этого не исправит.

Отсюда правило настройки хостинга, которое стоит знать наизусть: файлы с хэшем в имени — кэшировать надолго, index.html — не кэшировать. Это единственная настройка, которую стоит проверить руками при первой публикации сайта.

Сервер: обновление задевает тех, кого не ждали

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

Переименовали поле в ответе API — приложения, выпущенные полгода назад, перестали показывать погоду. Сделали поле обязательным в запросе — старые версии перестали отправлять данные. Формально ты поменял свой сервер; реально ты сломал программы, которые уже стоят у людей.

Правило, которое из этого следует:

  • добавлять поля можно, старые клиенты их просто не заметят;
  • удалять и переименовывать — нельзя, пока живы те, кто ими пользуется;
  • если изменение неизбежно — рядом появляется /api/v2/, а /api/v1/ продолжает работать (статья 7.3).

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

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

Магазин: что происходит после загрузки

измерено
загрузили  →  проверка  →  доступно части людей  →  доступно всем

Проверка занимает от часов до дней и может закончиться отказом. Самые частые причины отказа не технические: разрешения без объяснения (статья 12.2), нерабочая демонстрация для проверяющего, отсутствие политики конфиденциальности, если приложение собирает хоть что-нибудь.

Поэтапная раскатка — выдать новую версию сначала небольшой доле пользователей — единственная защита от того, что откатить публикацию нельзя. Если в первые сутки посыпались падения, раскатку останавливают, и большинство людей так и остаётся на работающей старой версии.

Как сказать ИИ

Публикация — это та область, где от ИИ полезнее всего получать списки проверок, а не действия.

Запрос
Я меняю ответ API: поле "temp" становится "temperature".
Мои мобильные приложения в магазине обновляются не сразу.
Что сломается у тех, кто на старой версии?
Предложи способ сделать это изменение без поломки.
Запрос
Я добавляю в базу обязательное поле. Напиши порядок
действий: что выкладывать первым, что вторым и что
произойдёт, если выложить в обратном порядке.
Отдельно: какая часть этого не откатывается.

Второй запрос стоит задавать всегда, когда меняется база. Ответ на вопрос «что не откатывается» — это и есть список того, что надо делать осторожно.

Запрос
Вот настройки кэширования моего хостинга: <настройки>.
Файлы сборки имеют хэш в имени, index.html — нет.
Что настроено неправильно и к чему это приведёт?
Запрос
Составь чек-лист публикации для моего проекта: <описание>.
Раздели на «до публикации», «сразу после» и «через сутки».
Только то, что относится к моему стеку.

На что смотреть

Изменение API без мысли о старых клиентах. Поле переименовано, версия не добавлена. Работает у тебя, сломано у тех, кто не обновился.

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

index.html кэшируется. Публикации перестают доходить до пользователей, и причину ищут в коде.

Нет способа узнать, что сломалось. После публикации нужны логи и сообщения об ошибках, иначе о поломке сообщат пользователи — или не сообщат.

Публикация делается руками и по памяти. Пока это пять команд в терминале, которые ты помнишь, — однажды ты выполнишь их в другом порядке.

Версия не видна в приложении. Когда пользователь жалуется, первый вопрос — какая у него версия. Если её негде посмотреть, разговор не состоится.

Миграция без проверки на копии данных. Запуск изменения структуры сразу на настоящей базе — самый дорогой из возможных способов узнать, что в нём ошибка.

Шпаргалка

  • После публикации версий всегда несколько: думай о тех, кто на старой.

  • Сайт откатывается мгновенно, сервер — если готовился, приложение — никогда.

  • Хэш в имени файла — защита от кэша; index.html кэшировать нельзя.

  • «Старое в браузере» — проверь инкогнито, прежде чем искать в коде.

  • В API можно добавлять, нельзя удалять и переименовывать.

  • Сначала поле в базе, потом код; удаления — отдельно и позже.

  • Откат кода есть, откат базы — нет.

  • Раскатывай на часть пользователей и не публикуй в пятницу.