# ADR-070: Обновление сверяется с версией оболочки, а не со счётчиком перезагрузок

Заменяет второй замок из [ADR-068](068-pwa-self-update.md): растущая пауза уходит, различение петли и релиза остаётся.

## Контекст

ADR-068 закрыл петлю перезагрузок двумя замками. Второй — пауза, которая удваивается с каждой перезагрузкой ради обновления: 30 секунд, минута, две, четыре. Считает её счётчик `bare-updates` в `sessionStorage`; он только растёт и обнуляется лишь смертью вкладки.

Счётчик не различает петлю и обычный релиз. Каждая законная перезагрузка удваивает паузу перед следующей, и вкладка, которая живёт долго, обновляться перестаёт: после десятого релиза ждать четыре часа, после двенадцатого — сутки. Долгоживущая вкладка — это ровно установленное на «Домой» приложение, которое не закрывают неделями, то есть тот самый случай, ради которого ADR-068 и написан. Защита от петли отменяла фичу, которую защищала.

Различие между петлёй и релизом есть, и оно не в числе перезагрузок: **при петле версия оболочки после перезагрузки не меняется, при релизе меняется**. Сервер, отдающий новый файл воркера на каждый запрос, отдаёт ту же оболочку — версия в `sw.js` пишется руками при релизе (`docs/deploy.md`), и сама собой она не меняется.

## Решение

- `sw.js` отвечает на сообщение `version` своей константой `VERSION`. Ответ уходит каналом вопроса (`MessageChannel`): вопросов бывает два подряд и к разным воркерам.
- Страница спрашивает версию у своего контроллёра при запуске. Это версия оболочки, код которой она исполняет: модули пришли из кэша именно этого воркера.
- Смена контроллёра ведёт к перезагрузке, только если версия включившейся оболочки другая. Та же версия означает, что сервер отдал другой файл воркера при неизменной оболочке: перезагрузка вернула бы ту же самую страницу, и следующий запрос за `sw.js` начал бы всё сначала. Петля обрывается здесь и целиком — перезагрузок в ней не случается вовсе.
- Версия, которой не назвали (воркер прежнего выпуска такого вопроса не знает, ответа нет за три секунды), считается другой: обновление до выпуска, который отвечает, важнее. Повторяться этому не с чего — после перезагрузки отвечают оба.
- Первая установка запоминает версию нового контроллёра: страница пришла из сети, и оболочка, которую она исполняет, — та, что только что встала.
- Пауза между перезагрузками остаётся, но постоянная — 30 секунд, и `bare-updates` уходит. Замком от петли она больше не служит; это предел частоты на случай сервера, который отдаёт разные версии на каждый запрос. Отметка времени `bare-updated-at` остаётся в `sessionStorage`.
- Отложенная паузой перезагрузка возвращается сама, по таймеру: другого повода может и не быть — поля пусты, вкладка открыта, а вкладка спрашивает сервер об обновлении только при запуске и при возвращении в приложение (ADR-068).

## Следствия

- Десять релизов подряд за жизнь одной вкладки доезжают все и через одну и ту же паузу: замер — 29–30 секунд на релиз. Прежний замок на тех же релизах давал 30, 60, 120, 240 секунд и дальше вдвое.
- Сервер, отдающий новый `sw.js` на каждый запрос при неизменной версии, перезагрузок не вызывает ни одной. Воркер он при этом меняет — это дело браузера, и стоит оно одной установки в минуту, не чаще: чаще страница сервер не спрашивает.
- Релиз без смены `VERSION` страницу не перезагружает. Это не новое ограничение: ADR-023 обещал такому релизу только обновление статики по ETag.
- В `sw.js` появился второй вопрос от страницы. Протокола (`docs/protocol.md`) это не касается: разговор идёт внутри браузера.
- `docs/storage.md`: у клиента остаётся один ключ в `sessionStorage` вместо двух.
